Wpf BackgroundWorker与NotifyPropertyChanged问题
我有一个WPF应用程序,它在BackgroundWorker中执行一些计算。问题是,当我尝试在RunWorkerCompleted事件处理程序中更新属性(调用setter中的NotifyPropertyChanged)时,我得到InvalidOperationException-Wpf BackgroundWorker与NotifyPropertyChanged问题,wpf,thread-safety,backgroundworker,Wpf,Thread Safety,Backgroundworker,我有一个WPF应用程序,它在BackgroundWorker中执行一些计算。问题是,当我尝试在RunWorkerCompleted事件处理程序中更新属性(调用setter中的NotifyPropertyChanged)时,我得到InvalidOperationException-调用线程无法访问此对象,因为其他线程拥有它。 说BackgroundWorker自己处理线程同步,所以我不应该关心使用Dispatcher。但我发现它不能正确处理NotifyPropertyChanged 有人能帮我解决
调用线程无法访问此对象,因为其他线程拥有它。
说BackgroundWorker自己处理线程同步,所以我不应该关心使用Dispatcher。但我发现它不能正确处理NotifyPropertyChanged
有人能帮我解决这个问题吗
编辑
这是我的代码(对于一些不相关的功能,我很抱歉):
backgroundWorker.DoWork+=委托(对象发送方,DoWorkEventArgs参数)
{
var action=(Func)args.Argument;
args.Result=BitmapUtil.BitmapSourceFromBitmap(action());
};
backgroundWorker.RunWorkerCompleted+=委托(对象发送方,RunWorkerCompletedEventArgs参数)
{
if(args.Cancelled | |(args.Error!=null))
{
返回;
}
ImageProcessed=(BitmapSource)args.Result;
};
...
已处理公共位图源图像
{
获取{return imageProcessed;}
设置
{
图像处理=值;
OnPropertyChanged(VMUtil.GetNameOf(vm=>vm.ImageProcessed));
}
}
问题不是由RunWorkerCompleted
中的任何代码引起的。该代码在创建BackgroundWorker
的同一线程上运行。问题在于实际在后台运行的方法
如果没有看到代码,很难说问题出在哪里。您正在默默地丢弃该方法抛出的任何错误,而不是记录或报告args.Error
中的内容,这一事实也可能导致问题。问题不是由RunWorkerCompleted
中的任何代码引起的。该代码在创建BackgroundWorker
的同一线程上运行。问题在于实际在后台运行的方法
如果没有看到代码,很难说问题出在哪里。您正在默默地丢弃该方法抛出的任何错误,而不是记录或报告args.Error中的内容,这一事实也可能导致问题。这似乎是一个跨线程问题,请尝试以下操作:
public BitmapSource ImageProcessed
{
get
{
return imageProcessed;
}
set
{
imageProcessed = value;
// bring the following to the main thread
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
OnPropertyChanged(VMUtil.GetNameOf<ImageAnalyzerViewModel>(vm => vm.ImageProcessed));
});
}
}
已处理公共位图源图像
{
得到
{
已处理的返回图像;
}
设置
{
图像处理=值;
//将以下内容带到主线程
Deployment.Current.Dispatcher.BeginInvoke(()=>
{
OnPropertyChanged(VMUtil.GetNameOf(vm=>vm.ImageProcessed));
});
}
}
这似乎是一个跨线程问题尝试以下方法:
public BitmapSource ImageProcessed
{
get
{
return imageProcessed;
}
set
{
imageProcessed = value;
// bring the following to the main thread
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
OnPropertyChanged(VMUtil.GetNameOf<ImageAnalyzerViewModel>(vm => vm.ImageProcessed));
});
}
}
已处理公共位图源图像
{
得到
{
已处理的返回图像;
}
设置
{
图像处理=值;
//将以下内容带到主线程
Deployment.Current.Dispatcher.BeginInvoke(()=>
{
OnPropertyChanged(VMUtil.GetNameOf(vm=>vm.ImageProcessed));
});
}
}
请显示一些有关如何设置属性的代码。这篇文章有点误导,因为DoWork函数中的对象位于另一个线程中,不能直接在线程外使用。请显示一些有关如何设置属性的代码。这篇文章有点误导人,因为DoWork函数中的对象位于另一个线程中,不能直接在线程外使用。但是如果我在属性更新的注释行(ImageProcessed=(BitmapSource)args.Result;)或者甚至在PropertyChanged调用上,一切都正常。哦,糟了。您正在后台线程上创建BitmapSource
,它是一个DispatcherObject
,因此具有线程关联性。您可以通过在位图源
上调用冻结
来解决问题;如果没有,您可能需要创建实际的BitmapSource
对象(这可能不是操作中运行缓慢的部分)在RunWorkerCompleted
中。但是,如果我不调用PropertyChanged,您如何解释一切工作正常?提升PropertyChanged会使UI线程尝试访问该对象。但是如果我在属性更新的注释行(ImageProcessed=(BitmapSource)args.Result;)或者甚至调用PropertyChanged,一切工作正常。哦,糟了。您正在后台线程上创建BitmapSource
,它是一个DispatcherObject
,因此具有线程关联性。您可以通过在位图源
上调用冻结
来解决问题;如果没有,您可能必须在RunWorkerCompleted
中创建实际的BitmapSource
对象(这可能不是操作中运行缓慢的部分)。但是,如果我不调用PropertyChanged,您如何解释一切工作正常?提高PropertyChanged会使UI线程尝试访问该对象。