【问题标题】:Best approach to Timeout using HttpWebRequest.BeginGetResponse使用 HttpWebRequest.BeginGetResponse 的最佳超时方法
【发布时间】:2012-05-16 21:24:18
【问题描述】:

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

我阅读了一些方法来获得相同的结果,但我不知道这是否是最好的方法,我是否应该使用几次调用,或者我可以在循环内缩放它(我正在做一个网络爬虫)。

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

【问题讨论】:

  • 它给你带来了什么问题,你有很多异步请求使用等待超时的资源吗?为什么不让它超时。
  • 你没有考虑过使用TPL吗?
  • 我应该在哪里使用 TPL?我正在使用 Tasks 调用此方法,但不在方法内部
  • @BenRobinson 我的网络爬虫让我配置我同时下载的数量。如果我让它超时,当我调用取消令牌时,我需要等待所有下载超时

标签: c# asynchronous httpwebrequest timeout waithandle


【解决方案1】:

BeginGetResponse 的 MSDN 文档有一个很好的例子来说明如何处理超时。它在我的网络爬虫中运行得很好。

【讨论】:

  • 我正在做类似的事情,但我使用的是 WaitHandle.WaitAny 而不是 ManualResetEvent。它允许更简洁的代码
猜你喜欢
  • 1970-01-01
  • 2011-05-21
  • 1970-01-01
  • 1970-01-01
  • 2012-08-11
  • 2021-07-05
  • 2021-12-23
  • 2012-12-22
  • 1970-01-01
相关资源
最近更新 更多