问题
I'm having trouble getting DownloadProgressChangedEventHandler to fire. I understand that, worst case, the event handler should fire every 64Kb. The URL I'm trying to download data from creates 680Kb of XML data on the fly, but the handler does not fire at all.
Here's test code that demonstrates the problem. Unfortunately I cannot share the specific URL as it contains proprietary data.
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);
}
回答1:
Your code looks ok, but documentation says "This event is raised each time an asynchronous download makes progress" while you are using synchronous version of the download. Switch to use DownloadFileAsync.
回答2:
My code was structured so that the WebClient
was already used on a non-UI thread, so I extended WebClient
to allow for a synchronous call to get events. I also extended it to allow for a custom connection timeout (I was calling a web service that could take quite a while to respond). The new method DownloadFileWithEvents
internally calls DownloadFileAsync
and properly blocks until the appropriate complete event is received.
Here's the code in case it's useful to anyone:
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;
}
}
来源:https://stackoverflow.com/questions/9576670/webclient-downloadprogresschangedeventhandler-not-firing