使用WebClient快速失败

时间:2012-06-20 14:22:41

标签: c# webclient

使用modified WebClient,我定期从具有以下特征的服务下载数据:

  • 数据下载(~1GB)大约需要20分钟
  • 有时服务决定不返回任何数据(请求挂起),或者返回第一个字节需要几分钟到几个小时。

如果服务在合理(可配置)的时间内没有返回任何数据,我希望快速失败,同时为下载取得成功提供充足的时间。

似乎WebRequest.Timeout属性controls the total time for the request to complete,而ReadWriteTimeout控制数据传输开始后可用于读取数据的总时间。

我是否缺少一个可以控制建立连接和返回第一个字节之间等待的最长时间的属性?如果没有这样的财产,我该如何处理这个问题?

1 个答案:

答案 0 :(得分:2)

我不知道任何额外的超时属性将实现您正在寻找的结果。我想到的第一个想法是将一个处理程序附加到DownloadProgressChanged,它将更新一个标志以指示已收到数据(尽管并不总是准确的)。

使用TimerEventWaitHandle您可以在短时间内阻止(或处理异步,如果您愿意)并评估是否已收到任何数据。下面的代码不是一个完全充实的例子,而是一个如何实现它的想法。

using (var manualResetEvent = new ManualResetEvent(false))
using (var client = new WebClient())
{
    client.DownloadProgressChanged += (sender, e) => manualResetEvent.Set();
    client.DownloadDataAsync(new Uri("https://github.com/downloads/cbaxter/Harvester/Harvester.msi"));

    if (!manualResetEvent.WaitOne(5000))
        client.CancelAsync();
}

在上面的示例中,如果manualResetEvent.WaitOne被调用,true将返回DownloadProgressChanged。你可能想检查e.BytesReceived > 0并且只设置非零值,但我认为你明白了吗?