WebClient DownloadProgressChangedEventHandler未触发
问题描述:
我无法获取DownloadProgressChangedEventHandler触发。我明白,最糟糕的情况是,事件处理程序should fire every 64Kb。我试图从中下载数据的URL在运行中创建了680Kb的XML数据,但处理程序根本不会启动。WebClient DownloadProgressChangedEventHandler未触发
下面是演示问题的测试代码。很遗憾,我无法分享特定的网址,因为它包含专有数据。
static void Main(string[] args)
{
Console.WriteLine("Downloading data");
string url = "https://MyUrlThatRespondsWith680KbOfData";
string outputPath = @"C:\Temp\DeleteMe.xml";
using (WebClient webClient = new WebClient())
{
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(webClient_DownloadProgressChanged);
webClient.DownloadFile(url, outputPath);
}
Console.Write("Done");
Console.ReadKey(true);
}
static void webClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
Console.WriteLine("Download progress: " + e.BytesReceived);
}
答
我的代码的结构使WebClient
已经用在非UI线程上,所以我扩展了WebClient
以允许同步调用来获取事件。我还扩展它以允许自定义连接超时(我正在调用一个可能需要相当长时间才能响应的Web服务)。新方法DownloadFileWithEvents
内部调用DownloadFileAsync
并正确阻塞,直到收到相应的完整事件。
这里的情况下,它是任何人有用的代码:
public class MyWebClient : WebClient
{
//time in milliseconds
private int timeout;
public int Timeout
{
get
{
return timeout;
}
set
{
timeout = value;
}
}
public MyWebClient(int timeout = 60000)
{
this.timeout = timeout;
this.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(MyWebClient_DownloadFileCompleted);
}
EventWaitHandle asyncWait = new ManualResetEvent(false);
public void DownloadFileWithEvents(string url, string outputPath)
{
asyncWait.Reset();
Uri uri = new Uri(url);
this.DownloadFileAsync(uri, outputPath);
asyncWait.WaitOne();
}
void MyWebClient_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
asyncWait.Set();
}
protected override WebRequest GetWebRequest(Uri address)
{
var result = base.GetWebRequest(address);
result.Timeout = this.timeout;
return result;
}
}
是的,这做到了。 Lame,因为下载已经发生在专用线程上(其后续负责处理下载的数据。 – 2012-03-06 02:08:48