c# – WebClient DownloadFileAsync()阻止线程

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

正如我从日志中可以看到的那样正在下载文件(当然,文件正在增长).

这是我的代码

#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; // https://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应用程序,因此没有异步或等待.整个应用程序都是无响应的,没有窗口大小调整,按钮点击或文本框交互.

当我使用调试器时,我一直挂在OnPropertyChanged() – 方法(我认为因为这是大多数时间过去的地方)并获得以下调用堆栈:

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#

它没有挂在那里,当它走得更远时,它没有任何延迟.

解决方法

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

您可能还想查看属性中发生的事情 – 看看是否存在可以优化的低效率.

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

相关文章

目录简介使用JS互操作使用ClipLazor库创建项目使用方法简单测...
目录简介快速入门安装 NuGet 包实体类User数据库类DbFactory...
本文实现一个简单的配置类,原理比较简单,适用于一些小型项...
C#中Description特性主要用于枚举和属性,方法比较简单,记录...
[TOC] # 原理简介 本文参考[C#/WPF/WinForm/程序实现软件开机...
目录简介获取 HTML 文档解析 HTML 文档测试补充:使用 CSS 选...