来自已完成的线程的对象的InvalidOperationException

时间:2009-10-30 17:25:13

标签: wpf multithreading dependency-properties invalidoperationexception

在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:调用线程无法访问此对象,因为另一个线程拥有它。

如果创建对象的线程已完成,为什么它仍然拥有该对象?在这周围有什么。?

3 个答案:

答案 0 :(得分:2)

您在给定线程中创建的对象归该线程所有。这就是你得到InvalidOperationException的原因。如果您想在后台线程中设置属性,我建议让委托返回所需的值并从主线程调用SetValue。 (创建对象的线程)。

答案 1 :(得分:1)

WPF中的绝大多数对象都具有线程关联性。一旦在特定线程上创建,WPF对象将仅在从该线程使用时操作。几乎在对该对象执行的每个操作中都会强制执行此限制(与WinForms不同)。

您需要更改代码,以便在此方案的实际UI线程上创建Foo。

答案 2 :(得分:1)

假设SomeClass派生自DispatcherObject,创建它的线程运行消息泵,负责处理foo对象的消息。因此,如果该线程结束,则该对象不能再处理消息,这不是一个好主意。

在大多数情况下,您应该使用相同的UI线程来创建所有UI对象(或从DispatcherObject派生的任何其他内容,并确保它在应用程序的持续时间内运行。然后使用{{ 1}}从工作线程向它发送消息。