I'm trying to encapsulate the WebClient async download method so I can get an progress bar update while waiting for lengthy files to download. MSDN documentation indicates that FTPDownloadCompleted and FTPDownloadProgressChanged are on a different thread but they never fire. Maybe I'm going about this the wrong way, but I need to avoid synching up events, callbacks ect.. so I thought I'd try this route. I'm particularly curious as to why the events aren't firing if they're delegates on a different thread.
class downloadFTP
{
public delegate void ProgressBarUpdate(Int32 val);
ProgressBarUpdate progressBarUpdate;
WebClient webClient;
Int32 waitTime = 60;
Double percentComplete = 0;
Boolean transferComplete = false;
public Boolean TransferComplete { get { return transferComplete; } }
Byte[] downloadData = null;
public Boolean DownLoadFTPFile(String filename, ProgressBarUpdate pbUpdate)
{
Boolean result = false;
progressBarUpdate = pbUpdate;
AutoResetEvent waiter = new System.Threading.AutoResetEvent (false);
webClient = new WebClient();
webClient.Credentials = new NetworkCredential(user.userId, user.passWd);
webClient.DownloadDataCompleted += new DownloadDataCompletedEventHandler(FTPDownloadCompleted);
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(FTPDownloadProgressChanged);
webClient.DownloadDataAsync(new Uri(ftpURL + "//" + filename),waiter);
waiter.WaitOne(waitTime*1000);
return TransferComplete;
}
private void FTPDownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
percentComplete = e.ProgressPercentage;
}
private void FTPDownloadCompleted(object sender, DownloadDataCompl开发者_如何学PythonetedEventArgs e)
{
downloadData = e.Result;
transferComplete = true;
}
WebClient runs callbacks on the current SynchronizationContext (see AsyncOperationManager.CreateOperation).
If the current SynchronizationContext is a WinForms or WPF event loop, then your DownLoadFTPFile
method blocks the thread and events won't show up. Solution: Remove the AutoResetEvent.
精彩评论