我有2个NotificationObject对象充当视图模型。 First NotificationObject包含绑定到特定控件视图的属性,第二个NotificationObject包含一些使用Thread对象在另一个线程中执行的代码。我需要从第二个NotificationObject的运行代码更改第一个NotificationObject的属性。当我尝试这样做时,我得到一个异常“调用线程无法访问此对象,因为另一个线程拥有它。”
我认为我需要使用某种调度程序来访问这些属性,就像我在Windows Forms或经典WPF中那样,但是我无法在Prism MVVM中找到它。那么如何更改第一个NotificationObject的属性?
答案 0 :(得分:4)
我猜你在一个线程上创建了一些东西,并试图从另一个线程更新它,而WPF不允许这样做。只能从创建它们的线程修改对象。
通常所有对象都在主UI线程上创建,Dispatcher用于将异步消息传递给UI线程以更新这些对象。任何繁重的处理仍然可以在后台线程上完成,但是要更新您需要使用主UI线程的对象的属性。
例如,看起来像这样的东西会起作用:
MyNotificationObject obj = new MyNotificationObject;
obj.Items = MethodThatRunsOnBackgroundThread();
List<SomeObject> MethodThatRunsOnBackgroundThread()
{
var list = new List<SomeObject>();
// Do Work
Return list;
}
虽然这不会:
MyNotificationObject obj = new MyNotificationObject;
MethodThatRunsOnBackgroundThread(obj);
void MethodThatRunsOnBackgroundThread()
{
var list = new List<SomeObject>();
// Do Work
// This won't work since obj was created on UI thread
obj.Items = List<SomeObject>;
}
这是另一个有效的示例,因为它正在发送消息以将对象更新为创建对象的UI线程。
MyNotificationObject obj = new MyNotificationObject;
MethodThatRunsOnBackgroundThread(obj);
void MethodThatRunsOnBackgroundThread()
{
var list = new List<SomeObject>();
// Load List
Application.Current.Dispatcher.BeginInvoke(DispatherPriority.Background,
new Action(delegate {
obj.Items = list;
}));
}
答案 1 :(得分:0)
Application.Current.Dispatcher是最简单的解决方案..
在.NET 4.5中,幸运的是,这将不再是必要的了。
答案 2 :(得分:0)
必须在视图的UserControl对象中查找Dispatcher,而不是在模型视图的NotificationObject中查找。我认为从MVVM中的模型视图引用视图并不好,但我还没有找到更好的解决方案。