如何在C#中使用WebClient下载文件,同时触发事件处理程序并支持超时属性?

时间:2012-07-05 08:35:48

标签: c# timeout webclient downloadfile downloadfileasync

我正在开发一个C#项目来从互联网上下载文件。

我会在下载过程中展示它们的进展。 我应该支持超时财产。

我尝试使用 WebClient 类。 有 DownloadFile ()和 DownloadFileAsync ()函数。

  • 当我使用 DownloadFile ()函数时,我可以设置Timeout属性,覆盖 GetWebRequest ()函数。但是,我无法触发事件处理程序,因此无法显示进度。
  • 当我使用 DownloadFileAsync ()函数时,我可以触发事件处理程序,因此我可以显示进度。但是,在这种情况下,我无法设置超时。

从互联网上,我可以找到一些关于使用线程手动设置超时的方法的文章。

但是,我认为所有这些都是不正确的。他们在整个下载过程中设置超时。但根据文件的大小,下载时间会很短或很长。

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

答案 1 :(得分:1)

根据MSDN documentation on HttpWebRequest,您需要使用线程自行实现。

  

在异步请求的情况下,客户端应用程序负责实现自己的超时机制。以下代码示例演示了如何执行此操作。

上面的链接实际上提供了一个完整的示例,说明如何使用线程池和 ManualResetEvent (示例大约是50-100行代码)。

以上是上述解决方案的关键,代码引自MSDN示例。

  1. 使用异步 BeginGetResponse

    IAsyncResult result =(IAsyncResult)myHttpWebRequest.BeginGetResponse(new AsyncCallback(RespCallback),myRequestState);

  2. 使用 ThreadPool.RegisterWaitForSingleObject 来实现超时。

    ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle,new WaitOrTimerCallback(TimeoutCallback),myHttpWebRequest,DefaultTimeout,true);

  3. 使用 ManualResetEvent 保留主线程,直到请求完成或超时。

    public static ManualResetEvent allDone = new ManualResetEvent(false); allDone.WaitOne();

相关问题