如何在WebClient.DownloadFileAsync上实现超时

所以我认为Webclient.DownloadFileAysnc会有一个默认超时,但环顾文档我无法在任何地方找到任何关于它的东西所以我猜它没有。

我试图从互联网上下载文件,如下所示:

  using (WebClient wc = new WebClient()) { wc.DownloadProgressChanged += ((sender, args) => { IndividualProgress = args.ProgressPercentage; }); wc.DownloadFileCompleted += ((sender, args) => { if (args.Error == null) { if (!args.Cancelled) { File.Move(filePath, Path.ChangeExtension(filePath, ".jpg")); } mr.Set(); } else { ex = args.Error; mr.Set(); } }); wc.DownloadFileAsync(new Uri("MyInternetFile", filePath); mr.WaitOne(); if (ex != null) { throw ex; } } 

但是,如果我关闭我的WiFi(模拟一滴互联网连接)我的应用程序只是暂停,下载停止但它永远不会报告通过DownloadFileCompleted方法。

出于这个原因,我想在我的WebClient.DownloadFileAsync方法上实现超时。 这可能吗?

另外我使用.Net 4并且不想添加对第三方库的引用,因此不能使用Async/Await关键字

您可以使用WebClient.DownloadFileAsync()。 现在在计时器内你可以像这样调用CancelAsync():

 System.Timers.Timer aTimer = new System.Timers.Timer(); System.Timers.ElapsedEventHandler handler = null; handler = ((sender, args) => { aTimer.Elapsed -= handler; wc.CancelAsync(); }); aTimer.Elapsed += handler; aTimer.Interval = 100000; aTimer.Enabled = true; 

否则,请创建自己的weclient

  public class NewWebClient : WebClient { protected override WebRequest GetWebRequest(Uri address) { var req = base.GetWebRequest(address); req.Timeout = 18000; return req; } } 

创建一个WebClientAsync类,在构造函数中实现计时器。 这样您就不会将计时器代码复制并粘贴到每个实现中。

 public class WebClientAsync : WebClient { private int _timeoutMilliseconds; public EdmapWebClientAsync(int timeoutSeconds) { _timeoutMilliseconds = timeoutSeconds * 1000; Timer timer = new Timer(_timeoutMilliseconds); ElapsedEventHandler handler = null; handler = ((sender, args) => { timer.Elapsed -= handler; this.CancelAsync(); }); timer.Elapsed += handler; timer.Enabled = true; } protected override WebRequest GetWebRequest(Uri address) { WebRequest request = base.GetWebRequest(address); request.Timeout = _timeoutMilliseconds; ((HttpWebRequest)request).ReadWriteTimeout = _timeoutMilliseconds; return request; } protected override voidOnDownloadProgressChanged(DownloadProgressChangedEventArgs e) { base.OnDownloadProgressChanged(e); timer.Reset(); //If this does not work try below timer.Start(); } } 

如果在下载文件时丢失Internet连接,这将允许您超时。