我无法启动DownloadProgressChangedEventHandler。我理解,最坏的情况是事件处理程序should fire every 64Kb。我正在尝试下载数据的URL动态创建680Kb的XML数据,但处理程序根本不会触发。
这是演示此问题的测试代码。不幸的是,我无法共享特定的URL,因为它包含专有数据。
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);
}
答案 0 :(得分:4)
您的代码看起来没问题,但documentation说“当您使用同步版本的下载时,每次异步下载进行时都会引发此事件”。切换为使用DownloadFileAsync。
答案 1 :(得分:3)
我的代码是结构化的,因此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;
}
}