2013-04-09 39 views
1

在WinRT應用程序中,我有一個帶有一些圖片和一個Image myImage的FlipView myFlipView。在myFlipView的事件的SelectionChanged有以下方法:異步方法中的錯誤

async private void myFlipView_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     if (myFlipView == null) return; 

     Uri newUri = new Uri("ms-appx://" + (((BitmapImage)(((Image)(((ContentControl)(myFlipView.SelectedItem)).Content)).Source)).UriSource.AbsolutePath)); 
     StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(newUri); 
     WriteableBitmap wb = new WriteableBitmap(1, 1); 

     if (file != null) 
     { 
      using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read)) 
      { 
       await wb.SetSourceAsync(fileStream); 
      } 
     } 

     wb = ModifyPicture(wb); 
     myImage.Source = wb; 
    } 

綜上所述發現當前圖像的URI在myFlipView並設置圖像MYIMAGE但在ModifyPicture定義了一些修改。它可以在平板電腦上完美工作,但在使用鼠標的電腦上卻有一個錯誤。當我點擊連接到FlipView的箭頭非常快,然後myImage顯示錯誤的圖片。例如,如果在myFlipView中有10張圖片(p1,p2,...,p10),並且當前選擇了p1,當我在myImage上更改爲p2時,也會出現p2。但是當我在FlipView中點擊的速度非常快時,例如p9和myImage p8。我認爲這與事實有關,該方法被稱爲多次,但我不知道如何解決它。預先感謝您的幫助:)

+0

你可以給我整個項目,我可以檢查嗎? – Xyroid 2013-04-09 09:49:59

回答

1

除了或代替取消內部任務ma_il提到 - 你能打破/如果檢測到取消異步方法執行它應該被取消。例如。

private int myFlipView_SelectionChangedCallId; 
async private void myFlipView_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    if (myFlipView == null) return; 

    var callId = ++myFlipView_SelectionChangedCallId; 

    Uri newUri = new Uri("ms-appx://" + (((BitmapImage)(((Image)(((ContentControl)(myFlipView.SelectedItem)).Content)).Source)).UriSource.AbsolutePath)); 
    StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(newUri); 

    if (callId != myFlipView_SelectionChangedCallId) return; 

    WriteableBitmap wb = new WriteableBitmap(1, 1); 

    if (file != null) 
    { 
     using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read)) 
     { 
      await wb.SetSourceAsync(fileStream); 

      if (callId != myFlipView_SelectionChangedCallId) return; 
     } 
    } 

    wb = ModifyPicture(wb); 
    myImage.Source = wb; 
} 

此外,如果您ModifyPicture方法做任何繁重的像素處理 - 你想在後臺線程上運行它,等待它。

+0

我用Filip Skakun解決方案,現在它工作正常。謝謝你的幫助:) – 2013-04-13 10:19:04

+0

Nie ma za co。 :) – 2013-04-13 18:49:52

2

您應該保存已運行的Task/IAsyncOperation,並在事件處理程序完成之前再次調用時取消它。

See this article on how to cancel running tasks

僞代碼(因爲我不知道C#):

Task loadAndSetImage(uri) { 
    return new Task... 
} 

flipView_SelectionChanged { 
    if (myFlipView == null) return; 
    if (this.runningTask && !this.runningTask.IsCanceled) { 
     this.runningTask.Cancel(); 
    } 
    Uri newUri = new Uri("ms-appx://" + (((BitmapImage)(((Image)(((ContentControl)(myFlipView.SelectedItem)).Content)).Source)).UriSource.AbsolutePath)); 

    this.runningTask = loadAndSetImage(newUri); 
    this.runningTask.ContinueWith((t) => this.runningTask = null;); 
}