1

在 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。我想这与方法被多次调用但我不知道如何解决它有关。提前感谢您的帮助:)

4

2 回答 2

2

如果在事件处理程序完成之前再次调用事件处理程序,您可能应该保存已经运行的 Task/IAsyncOperation 并取消它。

请参阅这篇文章,了解如何取消正在运行的任务

伪代码(因为我不知道 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; );
} 
于 2013-04-09T10:41:16.300 回答
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 方法进行任何繁重的像素处理 - 您可能希望在后台线程上运行它并等待它。

于 2013-04-09T19:06:09.250 回答