c# - WebClient.DownloadProgressChanged : Console. WriteLine() 正在阻塞 UI 线程

标签 c# webclient downloadfileasync

我有以下简单代码:

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() 替换为代码以更新我的进度条(未在代码中显示)时,它起作用了。用户界面响应迅速。

最佳答案

你这样做的方式似乎是MSDN shows in its examples .我也试过了,得到了同样的结果。当在单独的线程中运行某些内容时,您会看到类似的行为,然后过快地回调主 UI 线程并用更新对其进行冲击。 UI 线程得到备份并有效地卡住。

DownloadProgressChanged 事件触发得非常快......似乎每秒数百次,这意味着它也在尝试快速写入控制台。

您可以限制写入控制台的频率,这将解决问题(我通过尝试下载 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 + "%)"
            );
    }
}

关于c# - WebClient.DownloadProgressChanged : Console. WriteLine() 正在阻塞 UI 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27261797/

相关文章:

c# - 用户控件之间的 WPF 通信

c# - 在另一个 Expression<Func> 中使用 Expression<Func> 映射 DTO 类

c# - JsonConvert.DeserializeObject<>(字符串)返回 $id 属性的空值

c# - 如何在 C# 中使用 WebClient 下载文件并触发事件处理程序并支持超时属性?

c# - 如何在C#中成功下载一个.exe文件?

C# DownloadSync 事件未触发

c# - ASP.Net MVC 应用程序看似忽略数据库连接字符串

c# - JavaScript 从 C# 背后的代码确认

c# - 使用 JSON Web 服务时出现奇怪的字符

javascript - WebClient 无法加载 Twitter 页面