Лучший подход к тайм-ауту с использованием HttpWebRequest.BeginGetResponse

HttpWebRequest.BeginGetResponse не учитывает свойства времени ожидания из HttpWebRequest (Timeout или ReadWriteTimeout).

Я прочитал некоторые подходы, чтобы получить те же результаты, но я не знаю, лучший ли это способ сделать это, и следует ли мне использовать для нескольких вызовов или я могу масштабировать его внутри циклов (я делаю веб-краулер).

Важно то, что изначально мой код не асинхронный, мне просто нужен асинхронный, потому что мой метод должен принимать CancellationToken.

Меня беспокоят WaitHandles и ThreadPool.RegisterWaitForSingleObject. Это не ежедневный код, поэтому я не знаю, могут ли у меня возникнуть проблемы в ближайшем будущем.

private static void HandleCancellation(HttpWebRequest request, IAsyncResult getResponseResult, CancellationToken cancellationToken)
{
    using (WaitHandle requestHandle = getResponseResult.AsyncWaitHandle)
    {
        ThreadPool.RegisterWaitForSingleObject(requestHandle, TimeoutCallback, request, request.Timeout, true);

        //If request finish or cancellation is called
        WaitHandle.WaitAny(new[] {requestHandle, cancellationToken.WaitHandle});
    }

    //If cancellation was called
    if (cancellationToken.IsCancellationRequested)
    {
        request.Abort();
        cancellationToken.ThrowIfCancellationRequested();
    }
}

Вызов (опять же, это не асинхронно)

IAsyncResult getResponseResult = request.BeginGetResponse(null, null);

HandleCancellation(request, getResponseResult, cancellationToken);

return (HttpWebResponse)request.EndGetResponse(getResponseResult);

Ссылка: Лучший подход к управлению несколькими WebRequest


person Felipe Pessoto    schedule 08.05.2012    source источник
comment
Какую проблему это вызывает у вас, у вас есть много асинхронных запросов, использующих ресурсы, ожидающие тайм-аута? Почему бы не дать ему просто тайм-аут.   -  person Ben Robinson    schedule 08.05.2012
comment
Вы не думали использовать TPL?   -  person abatishchev    schedule 08.05.2012
comment
Где я должен использовать TPL? Я использую Tasks для вызова этого метода, но не внутри метода   -  person Felipe Pessoto    schedule 08.05.2012
comment
@BenRobinson, мой веб-краулер, позволяет мне настроить количество одновременных загрузок. Если я позволю тайм-ауту, когда я вызываю токен отмены, мне нужно дождаться тайм-аута всех загрузок.   -  person Felipe Pessoto    schedule 08.05.2012


Ответы (1)


Документация MSDN для BeginGetResponse имеет очень хороший пример того, как обрабатывать тайм-ауты. Это работало довольно хорошо для меня в моем веб-сканере.

person Jim Mischel    schedule 10.05.2012
comment
Я делаю что-то подобное, но использую WaitHandle.WaitAny вместо ManualResetEvent. Это позволяет более чистый код - person Felipe Pessoto; 10.05.2012