我目前正在使用优秀的WriteableBitmapEx Framework为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;
}
答案 0 :(得分:1)
好吧,正如我所提到的,将async
添加到方法中并不能使它以异步方式自动执行。它只是意味着编译器会将其转换为状态机,这使得编写continuation变得更容易。
在后台处理它的最简单方法是将计算包装在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;
}
答案 1 :(得分:1)
由于这种图像编辑似乎需要在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;
}