2014-11-22 92 views
2

我正在閱讀有關異步等待編程,我很困惑在一個場景中,我想使一個函數異步運行。例如,我想在我的用戶界面上顯示圖像。所以,在UI線程上,我調用了一個函數,它可以從存儲中獲取圖像並將圖像應用到UI上。如何使函數運行異步

這樣做的正確方法是什麼?

方法1

private async void SetImage() 
{ 
    await Task.Run(() => 
    { 
     byte[] fullViewImageBytes = Utils.GetImageFromStorage(fileName); 

     if (fullViewImageBytes != null) 
     { 
      Deployment.Current.Dispatcher.BeginInvoke(() => 
      { 
       MemoryStream memStream = new MemoryStream(fullViewImageBytes); 
       BitmapImage image = new BitmapImage(); 
       image.SetSource(memStream); 
       userImage.Source = image; 
      }); 
     } 
    } 
} 

方法2

private async void SetImage() 
{ 
    await Task.Delay(1); 

    byte[] fullViewImageBytes = Utils.GetImageFromStorage(fileName); 

    if (fullViewImageBytes != null) 
    { 
     MemoryStream memStream = new MemoryStream(fullViewImageBytes); 
     BitmapImage image = new BitmapImage(); 
     image.SetSource(memStream); 
     userImage.Source = image; 
    } 
} 
+2

這些都不實際使用的背後異步等待電源。如果有的話,'GetImageFromStorage'應該是一個異步操作,這可能是唯一需要等待的事情。請注意,您應該有一個「異步任務」簽名。 – 2014-11-22 20:30:53

回答

4

由於從磁盤讀取文件主要是關於異步IO,你可以採取advant Windows Phone平臺提供的各種異步API的時代。

沒有必要使用Task.Factory.StartNewTask.Run,這意味着根本不需要額外的ThreadPool線程。目前,您的代碼並不是真正的異步,並且請注意async void僅適用於頂級事件處理程序,不應以其他方式使用。

您可以利用異步API如下:

public async Task<BitmapImage> CreateImageFromFileAsync(string imagePath) 
{ 
    StorageFile storageFile = await StorageFile.GetFileFromPathAsync(imagePath); 
    IRandomAccessStream imageFileStream = await storageFile.OpenReadAsync(); 

    BitmapImage image = new BitmapImage(); 
    await image.SetSourceAsync(imageFileStream); 

    return image; 
} 
0

事情是這樣的:

private static async Task<BitmapImage> GetImageFromStorageAsync(string fileName) 
{ 
    var bytes = await Task.Factory 
       .StartNew((f)=>Utils.GetImageFromStorage((string)f), fileName) 
       .ConfigureAwait(false); 
    MemoryStream memStream = new MemoryStream(bytes); 
    BitmapImage image = new BitmapImage(); 
    image.SetSource(memStream); 
    return image; 
} 

private async Task SetImage() 
{ 
    var image = await GetImageFromStorageAsync(fileName); 
    userImage.Source = image; 
}