我目前正在使用强大的WriteableBitmapEx框架为Windows Store (WinRT)编写一个小的图像编辑应用程序。因为像.convolute这样的功能在WinRT设备上可能需要一段时间(在Surface上测试),所以我想让这些请求异步进行,这样UI就不会被阻塞,我可以显示一个进度环。
这就是我到目前为止所尝试的,代码本身是有效的。但是UI仍然会被阻塞,并且环不会显示。代码确实需要大约2秒的时间才能执行。
// Start Image editing when selection is changed
private async void FilterListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
progressRing.IsActive = true;
try
{
filteredImage = await FilterMethod.imageBW(originalImage, filteredImage);
}
catch
{
Debug.WriteLine("No items selected");
}
mainImage.Source = filteredImage;
progressRing.IsActive = false;
}
// Black & White
public static async Task<WriteableBitmap> imageBW(WriteableBitmap originalImage, WriteableBitmap filteredImage)
{
filteredImage = originalImage.Clone();
using (filteredImage.GetBitmapContext())
{
filteredImage.ForEach(ImageEdit.toGrayscale);
}
return filteredImage;
}
// Grayscale
public static Color toGrayscale(int x, int y, Color color)
{
byte gray = (byte)(color.R * .3f + color.G * .59f + color.B * .11f);
Color newColor = Color.FromArgb(255, gray, gray, gray);
return newColor;
}发布于 2013-06-18 00:30:00
由于这种图像编辑似乎需要在UI线程上进行,因此我能够将代码包装在
await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {}块,所以现在它看起来像这样:
private async void FilterListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
progressRing.IsActive = true;
try
{
await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
filteredImage = await FilterMethod.imageBW(originalImage, filteredImage);
}
}
catch
{
Debug.WriteLine("No items selected");
}
mainImage.Source = filteredImage;
progressRing.IsActive = false;
}发布于 2013-06-17 16:42:13
好的,正如我所提到的,将async添加到方法中并不会使其以异步方式自动执行操作。它只是意味着编译器会将其转换为状态机,这使得编写延续变得更容易。
在后台处理它的最简单方法是将计算包装在Task中。不过,我不太确定位图的跨线程编组是什么样子的:
private async void FilterListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
progressRing.IsActive = true;
try
{
var filteredImage = await Task.Run(() =>
{
var clonedBitmap = originalImage.Clone();
using (clonedBitmap.GetBitmapContext())
{
clonedBitmap.ForEach(ImageEdit.toGrayscale);
}
return clonedBitmap;
});
mainImage.Source = filteredImage;
}
catch
{
Debug.WriteLine("No items selected");
}
progressRing.IsActive = false;
}https://stackoverflow.com/questions/17136767
复制相似问题