在WinRT应用程序中,我有一个FlipView myFlipView,其中包含一些图片和一个Image myImage。在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;
}
总结一下,它在myFlipView中查找当前图像的uri并在myImage中设置该图像,但在ModifyPicture中定义了一些修改。它适用于平板电脑,但在有鼠标的计算机上有一个错误。当我单击快速附加到FlipView的箭头时,myImage会显示错误的图片。例如,如果在myFlipView中我有10张图片(p1,p2,...,p10)并且当前选择了p1,当我在myImage上更改为p2时,也会出现p2。但是当我有时在FlipView中非常快地点击时,我有例如p9和myImage p8。我想它与事实有关,这个方法被多次调用,但我不知道如何修复它。提前感谢您的帮助:)
答案 0 :(得分: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; );
}
答案 1 :(得分:1)
除了作为ma_il提及取消内部任务之外或代替取消内部任务 - 如果检测到应该取消异步方法执行,则可以中断/取消异步方法执行。 E.g。
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方法执行任何重度像素处理 - 您可能希望在后台线程上运行它并等待它。