2016-09-07 53 views
0

我有一个窗口,它使用了一些异步方法。然而,这只是挂UI(在这些行动)只有当我创建它在运行时,像这样:异步方法挂起UI

private void button_Click(object sender, RibbonControlEventArgs e) 
{ 
    AboutWindow SettingsWindow = new AboutWindow(); 
    SettingsWindow.ShowDialog(); 
} 

但是,如果我创造这样的:

private AboutWindow SettingsWindow = new AboutWindow(); 
private void button_Click(object sender, RibbonControlEventArgs e) 
{ 
    SettingsWindow.ShowDialog(); 
} 

一切似乎是确定并没有挂用户界面。

窗口内的方法,引起的问题介绍如下:

private async void CallUpdateDownload() 
{ 
    UpdaterStatus.CurrentUpdateStatus = await DownloadAndSaveInstallerAsync(UpdaterStatus.freshVersion); 
} 

public static async Task<UpdateStatus> DownloadAndSaveInstallerAsync(string NewVersion) 

主要挂在本字符串内DownloadAndSaveInstallerAsync发生:

CloudBlockBlob blob = new CloudBlockBlob(new Uri(sas)); 
MemoryStream msRead = new MemoryStream(); 
blob.DownloadToStream(msRead); // HANGS HERE 

问题是,为什么这个发生?为什么在开始时创建窗口会阻止它从异步方法中挂起。

另一个问题是,那我有另外一个对象,它也用DownloadAndSaveInstallerAsync的方法。这些对象是在运行时创建的,我无法做任何事情来防止这种挂起,下载时发生。

如何防止UI挂在这种情况下(在运行时创建对象)?

下面详细代码:

 private async void CallUpdateDownload() 
       { 
        UpdaterStatus.CurrentUpdateStatus = await UpdaterLogic.DownloadAndSaveInstallerAsync(UpdaterStatus.freshVersion); 
       } 

UpdaterLogic:

 public static async Task<UpdateStatus> DownloadAndSaveInstallerAsync(string NewVersion) 
       { 
     //... 
          if (await SaveInstallerToMemoryAsync(NewVersion)) 
           { 
             return UpdateStatus.ReadyToInstall; 
           } 
           else 
           { 
            return UpdateStatus.Error; 
           } 
       } 

    private static async Task<bool> SaveInstallerToMemoryAsync(string NewVersion) 
      { 
         using (MemoryStream ms = await UpdaterClient.DownloadInstallerAsync(NewVersion)) 
         using (FileStream fs = new FileStream(UpdaterSettings.Path), FileMode.Create)) 
         { 
          if (ms == null) return false; 
          ms.Position = 0; 
          await ms.CopyToAsync(fs); 
          fs.Close(); 
          ms.Close(); 
          return true; 
         } 
      } 

UpdaterClient:

public static async Task<MemoryStream> DownloadInstallerAsync(string version) 
      { 
         string sas = await GetInstallerDownloadLinkAsync(version); 

         CloudBlockBlob blob = new CloudBlockBlob(new Uri(sas)); 

          MemoryStream msRead = new MemoryStream(); 
          blob.DownloadToStream(msRead); 
          return msRead; 
      } 

public static async Task<string> GetInstallerDownloadLinkAsync(string version) 
     { 
        HttpResponseMessage response = null; 
         response = await httpClient.GetAsync(UpdaterSettings.Link + version); 
        if (response.IsSuccessStatusCode) 
        { 
         var res = await response.Content.ReadAsStringAsync(); 
         return res.Trim('"'); 
        } 
     } 
+0

你在等待里面'DownloadAndSaveInstallerAsync'? –

+0

创建设置窗口(在构造函数等等中)或窗口显示时,“CallUpdateDownload”方法是否运行? – mcy

+0

里面有一个'await SaveInstallerToMemoryAsync(NewVersion)'的方法,这个头部是'private static async任务 SaveInstallerToMemoryAsync(string NewVersion)' - 这个方法可以和'blob'和'MemoryStream'一起使用 –

回答

1

,你必须执行一个任务/线程内长时间运行的零件和await他们避免阻塞。

public static async Task<MemoryStream> DownloadInstallerAsync(string version) 
{ 
    string sas = await GetInstallerDownloadLinkAsync(version); 

    CloudBlockBlob blob = new CloudBlockBlob(new Uri(sas)); 

    MemoryStream msRead = new MemoryStream(); 
    await Task.Run(() => blob.DownloadToStream(msRead)); 
    return msRead; 
} 

更新

CloudBlockBlob确实提供了一个DownloadToStreamAsync方法,你可以用

public static async Task<MemoryStream> DownloadInstallerAsync(string version) 
{ 
    string sas = await GetInstallerDownloadLinkAsync(version); 

    CloudBlockBlob blob = new CloudBlockBlob(new Uri(sas)); 

    MemoryStream msRead = new MemoryStream(); 
    await blob.DownloadToStreamAsync(msRead); 
    return msRead; 
} 
+0

上找到相同行为的方式。万分感谢! –