在WPF应用程序中,我有一个创建对象的BackgroundWorker线程。让我们调用对象foo。
后台工作人员代码:
SomeClass foo = new SomeClass();
// Do some operation on foo
// Set some dependency property on the main class to foo
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
(SendOrPostCallback)delegate { SetValue(FooProperty, foo); },
foo);
现在,当主类尝试使用getter访问FooProperty时,我得到一个InvalidOperationException:调用线程无法访问此对象,因为另一个线程拥有它。
如果创建对象的线程已完成,为什么它仍然拥有该对象?在这周围有什么。?
答案 0 :(得分:2)
您在给定线程中创建的对象归该线程所有。这就是你得到InvalidOperationException的原因。如果您想在后台线程中设置属性,我建议让委托返回所需的值并从主线程调用SetValue。 (创建对象的线程)。
答案 1 :(得分:1)
WPF中的绝大多数对象都具有线程关联性。一旦在特定线程上创建,WPF对象将仅在从该线程使用时操作。几乎在对该对象执行的每个操作中都会强制执行此限制(与WinForms不同)。
您需要更改代码,以便在此方案的实际UI线程上创建Foo。
答案 2 :(得分:1)
假设SomeClass
派生自DispatcherObject
,创建它的线程运行消息泵,负责处理foo
对象的消息。因此,如果该线程结束,则该对象不能再处理消息,这不是一个好主意。
在大多数情况下,您应该使用相同的UI线程来创建所有UI对象(或从DispatcherObject
派生的任何其他内容,并确保它在应用程序的持续时间内运行。然后使用{{ 1}}从工作线程向它发送消息。