简体   繁体   English

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

[英]How can I download a file using WebClient in C# with firing the eventhandlers and supporting the timeout property?

I'm developing a C# project to download the files from the internet. 我正在开发一个C#项目,以从Internet下载文件。

I'll show the progresses of them while the downloads are going. 在下载过程中,我将展示它们的进度。 And I should support the time-out property. 我应该支持超时属性。

I've tried to use the WebClient class. 我试图使用WebClient类。 There are DownloadFile () and DownloadFileAsync () functions. DownloadFile ()和DownloadFileAsync ()函数。

  • When I use DownloadFile () function, I can set the Timeout property, overriding the GetWebRequest () function. 当我使用DownloadFile ()函数时,可以设置Timeout属性,以覆盖GetWebRequest ()函数。 However, I can't fire the event handlers, so I can't show the progresses. 但是,我无法触发事件处理程序,因此无法显示进度。
  • When I use DownloadFileAsync () function, I can fire the event handlers, so I can show the progresses. 使用DownloadFileAsync ()函数时,可以触发事件处理程序,因此可以显示进度。 But, in this case, I can't set the Timeout. 但是,在这种情况下,我无法设置超时。

From the internet, I can find some articles about the way to set the timeout manually using threading. 在互联网上,我可以找到一些有关使用线程手动设置超时方式的文章。

However, I think that all of them are incorrect. 但是,我认为所有这些都不正确。 They set the timeout during the entire download progress. 他们在整个下载过程中设置超时。 But the downloading will be short or long according to the size of the file. 但是根据文件的大小,下载的时间是短还是长。

How can I solve this problem? 我怎么解决这个问题?

Per the MSDN documentation on HttpWebRequest , you need to implement this yourself using threading. 根据HttpWebRequest上MSDN文档 ,您需要自己使用线程来实现。

In the case of asynchronous requests, it is the responsibility of the client application to implement its own time-out mechanism. 对于异步请求,客户端应用程序有责任实现自己的超时机制。 The following code example shows how to do it. 下面的代码示例演示如何执行此操作。

The above link actually gives a complete example of how to do this, using a thread pool and a ManualResetEvent (the example is about 50-100 lines of code). 上面的链接实际上给出了使用线程池和ManualResetEvent的完整示例(该示例约为50-100行代码)。

Here is the crux of the above solution, with code quoted from the MSDN example. 这是上述解决方案的症结所在,引用了MSDN示例中的代码。

  1. Use the asynchronous BeginGetResponse . 使用异步BeginGetResponse

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

  2. Use ThreadPool.RegisterWaitForSingleObject to implement the timeout. 使用ThreadPool.RegisterWaitForSingleObject实现超时。

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

  3. Use the ManualResetEvent to hold the main thread until either the request is complete, or timed out. 使用ManualResetEvent来保存主线程,直到请求完成或超时。

    public static ManualResetEvent allDone = new ManualResetEvent(false); 公共静态ManualResetEvent allDone =新的ManualResetEvent(false); allDone.WaitOne(); allDone.WaitOne();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM