使用HttpWebRequest.BeginGetResponse的Timeout最佳方法

时间:2012-05-08 11:37:56

标签: c# asynchronous httpwebrequest timeout waithandle

HttpWebRequest.BeginGetResponse不尊重来自HttpWebRequest(Timeout或ReadWriteTimeout)的任何Timeout属性。

我读了一些方法来获得相同的结果,但我不知道这是否是最好的方法,如果我应该使用几个调用或我可以在循环内扩展它(我正在做一个webcrawler)。

重要的是,最初我的代码不是异步的,我只需要异步,因为我的方法应该接受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);

参考:Better approach in management of multiple WebRequest

1 个答案:

答案 0 :(得分:3)

BeginGetResponse的MSDN文档提供了一个如何处理超时的非常好的示例。它在我的网络爬虫中对我很有用。