2012-06-20 231 views
4

使用modified WebClient快速失败了,我从服务具有以下特点定期下载数据:与Web客户端

  • 的数据下载(〜1GB),可采取大约20分钟
  • 有时,服务决定不完全返回任何数据(请求挂起),或者花费几分钟到几小时返回第一个字节。

如果服务没有在合理的(可配置的)时间内返回任何数据,而且还有足够的时间让下载成功,我希望快速失败。

看来,WebRequest.Timeout财产controls the total time for the request to complete,而ReadWriteTimeout控件可用的总时间来读取数据,一旦数据传输开始。

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

回答

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并只设置为非零值,但我认为您明白了吗?

+0

我害怕这将是确切的答案:-( –