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;); 
}