2

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

如果创建对象的线程已经完成,为什么它仍然拥有该对象?有什么办法吗?

4

3 回答 3

2

An object you create in a given thread is owned by that thread. That's why you're getting an InvalidOperationException. If you would like to set a property in a background thread, I recommend having the delegate return the desired value and calling SetValue from your main thread. (thread that created the object).

于 2009-10-30T17:32:50.593 回答
1

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

您将需要更改您的代码以在此场景的实际 UI 线程上创建 Foo。

于 2009-10-30T17:38:06.340 回答
1

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

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

于 2009-10-30T17:43:13.723 回答