【发布时间】:2015-11-04 09:45:44
【问题描述】:
我正在尝试使用 WebClient.DownloadFileAsync-Method 下载一些文件。 只要不显示 UI,它就可以正常工作。
UI 是一个带有标签和进度条的表单。
在 DownloadProgressChanged-Event 中,我想显示当前进度。 为了做到这一点,我调用了一个带有 int 参数的方法。 以下是下载方法:
private void DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
if(progressDialog!=null){
progressDialog.setFileProgress(e.ProgressPercentage);
}
Trace.WriteLine(String.Format("downloaded {0} of {1} bytes. {2} % complete...",
e.BytesReceived,
e.TotalBytesToReceive,
e.ProgressPercentage));
}
private void DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
if(progressDialog!=null){
progressDialog.setFileProgress(100);
}
are.Set();
}
private AutoResetEvent are = new AutoResetEvent(false);
public void DownloadFiles(List<DownloadObject> objects){
Trace.WriteLine("Start Download");
wc.DownloadProgressChanged += DownloadProgressChanged;
wc.DownloadFileCompleted += DownloadFileCompleted;
try{
foreach(DownloadObject dlo in objects){
currentFile = dlo;
String url = dlo.DownloadURL;
String path = dlo.LocalPath;
Uri uri = new Uri(url);
//GET
Thread thread = new Thread(() => wc.DownloadFileAsync(uri,path));
//thread.SetApartmentState(ApartmentState.STA);
thread.Start();
are.WaitOne();
DeleteFile(dlo.ID);
}
Trace.WriteLine("FileDownload finished");
}catch(Exception ex){
Trace.WriteLine("FileDownload failed: "+ex.Message);
}finally{
wc.Dispose();
}
}
这些是 ProgressDialog-Form 中的相关方法:
public delegate void dummy();
public void setFileProgress(int progress){
if(prgFile.InvokeRequired){
Trace.WriteLine("Invoke required");
prgFile.Invoke(new dummy(() => prgFile.Value = progress));
}else{
Trace.WriteLine("Invoke not required");
prgFile.Value = progress;
}
}
public static ProgressDialog getInstance(IWin32Window owner){
ProgressDialog pd = new ProgressDialog();
//pd.Show(owner); //
return pd;
}
现在发生的事情是这样的: 如果不调用 pd.Show() 一切都很好。进度发生了变化,我得到了“不需要调用”的输出以及下载的每个步骤。
但是,如果调用 pd.Show(),我会多次获得输出“需要调用”,而两者之间没有任何下载消息。
所以我调试了那部分代码,似乎调用了progressDialog.setFileProgress(),但在调用prgFile.Invoke-method 后,DownloadProgressChanged-Event 再次触发。
如果我将 Invoke 调用切换到 BeginInvoke,我会再次收到所有正确的消息,但 ProgressDialog 会冻结,直到所有下载完成并且我没有显示任何进度。
我在那里缺少什么?我阅读了大量关于此的问题和线程,但无法运行。
我正在使用带有 .Net-Framework 4.0 的 SharpDevelop
【问题讨论】: