WebClient DownloadFileAsync() 阻塞线程 [英] WebClient DownloadFileAsync() blocks thread

查看:65
本文介绍了WebClient DownloadFileAsync() 阻塞线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 WPF 和 MVVM 从我的网络服务器下载一个大文件 (500 mb).因此,以下属性都绑定到某种控件(进度条).问题是,即使在使用 DownloadFileAsync 时,应用程序仍然挂起.

I'm trying to download a large file (500 mb) from my webserver using WPF and MVVM. Thus the following properties are all bound to some kind of controls (progressbar). The problem is, that the application still hangs, even while using DownloadFileAsync.

文件正在被下载,我可以从我的日志中看出(当然,文件还在增长).

The file is being downloaded as I can tell from my logs (and the file growing, of course).

这是我的代码:

    #region Methods

    private void StartDownload(string url, string localPath)
    {
        Logger.Debug("Starting to initialize file download");

        if (!_webClient.IsBusy)
        {
            _webClient = new WebClient();
            _webClient.Proxy = null; // http://stackoverflow.com/questions/754333/why-is-this-webrequest-code-slow/935728#935728
            _webClient.DownloadFileCompleted += webClient_DownloadFileCompleted;
            _webClient.DownloadProgressChanged += webClient_DownloadProgressChanged;

            _webClient.DownloadFileAsync(new Uri(url), localPath);
        }

        Logger.Debug("Finished initializing file download");
    }

    private void webClient_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
    {
        Logger.Debug("Download finished! Cancelled: {0}, Errors: {1} ", e.Cancelled, e.Error);
    }

    private void webClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        Logger.Debug("Downloading... Progress: {0} ({1} bytes / {2} bytes)", e.ProgressPercentage, e.BytesReceived, e.TotalBytesToReceive);

        if (!IsDownloadPaused)
        {
            DownloadFileProgress = e.ProgressPercentage;
            BytesReceived = e.BytesReceived;
            TotalBytesToReceive = e.TotalBytesToReceive;
        }
        else
        {
            Logger.Debug("Download paused...");
        }
    }

    #endregion Methods

根据评论请求它是一个 .NET 4 CP 应用程序,因此没有 asyncawait.整个应用程序无响应,根本没有窗口大小调整、按钮点击或文本框交互.

Edit as per comment request: It's a .NET 4 CP application, thus no async or await. The entire application is going responseless, no window resizing, button clicking or textbox-interaction at all.

当我使用调试器时,我一直挂在 OnPropertyChanged()-Method 中(我认为这是因为大部分时间都在那里)并获得以下调用堆栈:

When I break in with the debugger, I keep hanging in the OnPropertyChanged()-Method (I think because that's where most of the time goes by) and get the following call stack:

Launcher.exe!Company.Product.Tools.Launcher.ViewModels.ViewModelBase.OnPropertyChanged(string propertyName) Line 16 + 0x59 bytes    C#
Launcher.exe!Company.Product.Tools.Launcher.ViewModels.DownloadViewViewModel.BytesReceived.set(long value) Line 82 + 0x21 bytes C#
Launcher.exe!Company.Product.Tools.Launcher.ViewModels.DownloadViewViewModel.webClient_DownloadProgressChanged(object sender, System.Net.DownloadProgressChangedEventArgs e) Line 216 + 0x3f bytes  C#

它不会挂那里,当进一步前进时,它没有任何延迟.

It doesn't hang there, when stepping further it goes without any delay.

推荐答案

听起来您收到了关于下载字节数的很多反馈,而属性更改事件处理程序的效率相对较低.也许您应该只限制更新 BytesReceived 的频率 - 通过时间(例如每秒更新五次)或增量(当它更改超过 K 时更新)或某些混合版本.

It sounds like you're getting lots of feedback about the number of bytes downloaded, and the property changed event handler is relatively inefficient. Maybe you should only limit how often you update BytesReceived - either by time (e.g. update it five times per second) or by delta (update it when it's changed by more than a K) or some hybrid version.

不过,您可能还想查看房产中发生的情况 - 看看那里是否存在可以优化的低效之处.

You might also want to look into what's happening in the property though - see whether there's anything inefficient there which you could optimize.

(第一步可能是计算 webClient_DownloadProgressChanged 被调用的次数.)

(The first step might be to keep a count of just how many times webClient_DownloadProgressChanged is called.)

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

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