WebClient.DownloadProgressChanged:Console.WriteLine()阻止UI线程 [英] WebClient.DownloadProgressChanged: Console.WriteLine() is blocking UI thread

查看:134
本文介绍了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()来更新进度条(未在代码中显示)时,它可以工作.用户界面具有响应性.

Why is this blocking the UI thread? When I replace the Console.WriteLine() with code to update my progress bar (not show in code), it works. The UI is responsive.

推荐答案

您的操作方式似乎是

The way you're doing it seems to be how MSDN shows in its examples. I tried it too and got the same result. You'll see similar behavior when running something in a separate thread, which then calls back to the main UI thread too quickly and pounds it with updates. The UI thread gets backed up and effectively freezes.

DownloadProgressChanged事件的触发速度非常快……似乎每秒发生数百次,这意味着它也试图快速写入控制台.

That DownloadProgressChanged event fires really quickly... appears to be hundreds of times per second, meaning it's trying to write to the console that quickly too.

您可以限制写入控制台的频率,以解决该问题(我尝试通过下载4GB ISO进行了测试,并在保持UI响应状态的同时写入了控制台):

You can limit how often you're writing to the console, which will resolve the issue (I tested it by trying to download a 4GB ISO, and it wrote to the console while leaving the UI responsive):

// 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 + "%)"
            );
    }
}

这篇关于WebClient.DownloadProgressChanged:Console.WriteLine()阻止UI线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆