我的程序中有两个图像,我有一个比较两个BitmapSource的函数,问题是我将一个ImageSource转换为BitmapSource并将其分配给一个变量,并将其发送到一个任务内的函数(因为该函数)是相当慢,我更喜欢使用一个任务,然后在完成后更新用户),它给我一个错误,任务不能使用这个变量,因为另一个线程拥有它...请帮我修复它。
private async void btnAnalyze_Click(object sender, RoutedEventArgs e)
{
if (AnalyzeImage?.Status == TaskStatus.Running) await AnalyzeImage;
var baseSource = (BitmapSource)imgBase.Source;
var newSource = (BitmapSource)imgNew.Source;
if (baseSource?.CompareSizeTo(newSource) == false)
{
ShowStatus("Images are different in size or at least one of them is null");
return;
}
btnAnalyze.IsEnabled = false;
ShowStatus();
try
{
AnalyzeImage = Task<BitmapSource>.Factory.StartNew(() => baseSource?.ConvertToBitmap().CompareTo(newSource?.ConvertToBitmap()).BitmapToImageSource());
InvokeA(() => waitingPanel.Visibility = Visibility.Visible);
await AnalyzeImage;
imgNew.Source = AnalyzeImage.Result;
}
catch (Exception ex) { Notify("Error in btnAnalyzeClick", ex, true); }
finally { InvokeA(() => waitingPanel.Visibility = Visibility.Hidden); }
}
答案 0 :(得分:1)
从DispatcherObject派生的对象具有线程关联性,即一旦创建,它们就被调用线程“拥有”。在WPF应用程序中,它通常是UI线程。
如果在BimtapSource
之后放置await
实例,它将使用当前上下文(在本例中为UI),这将允许UI组件使用此对象:
private async void btnAnalyze_Click(object sender, RoutedEventArgs e)
{
if (AnalyzeImage?.Status == TaskStatus.Running) await AnalyzeImage;
var baseSource = (BitmapSource)imgBase.Source;
var newSource = (BitmapSource)imgNew.Source;
if (baseSource?.CompareSizeTo(newSource) == false)
{
ShowStatus("Images are different in size or at least one of them is null");
return;
}
btnAnalyze.IsEnabled = false;
ShowStatus();
try
{
waitingPanel.Visibility = Visibility.Visible;
var worker = Task<Bitmap>.Factory.StartNew(() =>
baseSource?.ConvertToBitmap()
.CompareTo(newSource?.ConvertToBitmap()));
var bmp = await worker;
// The next statement is executed in UI synchronization context
imageNew.Source = bmp.BitmapToImageSource();
}
catch (Exception ex)
{
Notify("Error in btnAnalyzeClick", ex, true);
}
finally
{
waitingPanel.Visibility = Visibility.Hidden;
}
}