我試圖使用WebClient.DownloadFileAsync方法下載某些文件。 只要UI未顯示,它就可以正常工作。使用WebClient進行文件下載時UI凍結
UI是一個帶有標籤和ProgressBar的窗體。
在DownloadProgressChanged-事件中,我想顯示當前進度。 爲了做到這一點,我調用一個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();
}
}
這是相關methodsinside的ProgressDialog表格:
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()被調用,但DownloadProgressChanged事件直接調用prgFile.Invoke方法後直接觸發。
如果我切換調用,調用BeginInvoke來,我再次得到所有正確的消息,但ProgressDialog凍結,直至所有下載完成後,我就不會顯示任何進展。
我在那裏錯過了什麼?我通讀了大量有關此問題和線索的文章,但無法使其運行。
我使用的SharpDevelop與.net框架4.0
問題是,DeleteFile方法刪除服務器上的文件。因此,如果DownloadFileAsync尚未完成,我可能會遇到問題。此外,我需要使用Asnyc,因爲如果沒有它,我將無法獲得進度信息,但在刪除文件之前需要等待。我怎樣才能實現這個沒有AutoResetEvent?如果我不等待下載完成,則會出現Web客戶端無法同時下載多個文件的錯誤。 –
某處我讀了應該有一個webclient爲每個文件,但我認爲我的ProgressDialog會爆炸,如果我這樣做。 –
現在我試着把刪除放入完整的事件中,它發生了我的預測。首先我得到了WebClient無法同時下載多個文件的消息。然後我爲每個文件創建了一個新的Web客戶端,這導致了ProgressDialog的解鎖,但是進度條看起來像一個迪斯科舞會。也許我應該重新思考ProgressDialog並在數據網格中顯示多個文件或其他內容。 –