Search code examples
c#.net-4.0timeoutwebclient

How to implement a Timeout on WebClient.DownloadFileAsync


So I thought Webclient.DownloadFileAysnc would have a default timeout but looking around the documentation I cannot find anything about it anywhere so I'm guessing it doesn't.

I am trying to download a file from the internet like so:

 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;
        }
  }

But if I turn off my WiFi (simulating a drop of internet connection) my application just pauses and the download stops but it will never report that through to the DownloadFileCompleted method.

For this reason I would like to implement a timeout on my WebClient.DownloadFileAsync method. Is this possible?

As an aside I am using .Net 4 and don't want to add references to third party libraries so cannot use the Async/Await keywords


Solution

  • You can use WebClient.DownloadFileAsync(). Now inside a timer you can call CancelAsync() like so:

    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;
    

    Else create your own weclient

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