2014-12-03 166 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