2014-12-03 184 views
1

我有以下簡單的代碼:WebClient.DownloadProgressChanged:Console.WriteLine()是阻塞UI線程

private void btn_download_Click(object sender, EventArgs e){ 

    WebClient client = new WebClient(); 
    client.DownloadProgressChanged += client_DownloadProgressChanged; 
    client.DownloadFileAsync(new Uri("http://.../file.zip"), "file.zip"); 

} 

void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e){ 
    //Prints: "Downloaded 3mb of 61.46mb (4%)" 

    Console.WriteLine("Downloaded " 
     + ((e.BytesReceived/1024f)/1024f).ToString("#0.##") + "mb" 
     + " of " 
     + ((e.TotalBytesToReceive/1024f)/1024f).ToString("#0.##") + "mb" 
     + " (" + e.ProgressPercentage + "%)" 
    ); 
} 

這是爲什麼呢阻塞UI線程?當我用代碼替換Console.WriteLine()來更新我的進度條(不在代碼中顯示)時,它可以工作。用戶界面很敏感。

+0

是否有控制檯可以寫入?你爲什麼要從GUI程序寫入控制檯?在這裏使用'Debug'類還是'TraceListener'會更有意義? – 2014-12-03 00:54:42

+0

當文件完全下載時,是否至少更新一次? – 2014-12-03 00:57:54

+0

@PeterDuniho寫好控制檯基本上輸出到「標準輸出」,這可以在Visual Studio中的「輸出:窗口中查看。添加是的,這會更有意義,但我的問題不是要求替代品。知道背後的原因 – Krimson 2014-12-03 00:57:57

回答

4

你這樣做的方式似乎是MSDN shows in its examples。我也試過了,得到了同樣的結果。在單獨的線程中運行某些內容時,您會看到類似的行爲,然後這些線程會過快地回調主UI線程,並通過更新來加重它。 UI線程得到備份並有效凍結。

DownloadProgressChangedDownloadProgressChanged事件觸發得很快......似乎是每秒數百次,這意味着它試圖快速寫入控制檯。

你可以限制你多久寫到控制檯,這將解決這個問題(我測試了它,試圖下載一個4GB的ISO,並同時使UI響應寫信給控制檯):

// define a class-level field variable 
private int counter; 

private void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) 
{ 
    counter++; 

    // Only print to the console once every 500 times the event fires, 
    // which was about once per second when I tested it 
    if (counter % 500 == 0) 
    { 
     //Prints: "Downloaded 3mb of 61.46mb (4%)" 
     Console.WriteLine("Downloaded " 
          + ((e.BytesReceived/1024f)/1024f).ToString("#0.##") + "mb" 
          + " of " 
          + ((e.TotalBytesToReceive/1024f)/1024f).ToString("#0.##") + "mb" 
          + " (" + e.ProgressPercentage + "%)" 
      ); 
    } 
} 
+0

Perfect dude!這真是令人困惑我。 – Krimson 2014-12-03 02:40:42

+1

我可以ee爲什麼,因爲這正是他們似乎建議在文檔中做的事情!包括關於它多久發生一次火災的說明並不會傷害他們,但我想他們無法預測所有事情。 – 2014-12-03 02:41:57