2013-05-31 31 views
3

我试图从我的webserver使用WPF和MVVM下载一个大文件(500 MB)。因此,以下属性都绑定到某种控件(进度条)。问题是,应用程序仍然挂起,即使使用DownloadFileAsync。WebClient 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; // 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。整个应用程序无响应,无窗口大小调整,按钮点击或文本框交互。

当我打破与调试,我一直挂在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# 

它不挂那里,当进一步它没有任何延迟。

+1

你能在“挂起”阐述 - 它是完整的作品,根本不需要做任何UI事件(如窗口调整大小)看一看?如果你使用调试器,会发生什么情况 - 调用堆栈是什么样的? –

+0

您是否尝试过使用StartDownload async? –

+0

@JonSkeet我编辑了这些信息,谢谢! – SeToY

回答

7

这听起来像你得到很多有关下载的字节数的反馈,并且属性更改事件处理程序相对低效。也许你只应该限制你更新BytesReceived的时间 - 无论是按时间(例如每秒更新5次)还是按增量(当它改变超过K时更新)或某些混合版本。

虽然您可能还想查看房产中发生的情况,请查看您是否有可以优化的效率低下。

(第一步可能是保留的只是多少次webClient_DownloadProgressChanged称为计数)。

+0

好吧,一个快速测试(注释BytesReceived的赋值)让UI响应(按钮交互成为可能)...我认为这是问题,永久的PropertyChanged()导致UI变得疯狂。谢谢! – SeToY