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

发布于 2024-08-09 06:38:39 字数 500 浏览 11 评论 0原文

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

如果创建对象的线程已完成,为什么它仍然拥有该对象?有什么办法可以解决这个问题吗?

In a WPF application I had a BackgroundWorker thread creating an object. Let's call the object foo.

Background worker code:

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);

Now, when the main class tries to access FooProperty using a getter, I get an InvalidOperationException: The calling thread cannot access this object because a different thread owns it.

If the thread the create the object is finished, why does it still own the object? Is there someway around this.?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

听风念你 2024-08-16 06:38:39

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

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).

苍暮颜 2024-08-16 06:38:39

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

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

The vast majority of objects in WPF have thread affinity. That is once created on a particular thread, a WPF object will then only operate when used from that thread. This restriction is enforced (unlike WinForms) on practically every operation you do on that object.

You will need to change your code to have Foo created on the actual UI thread for this scenario.

喜爱纠缠 2024-08-16 06:38:39

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

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

Assuming SomeClass is derived from DispatcherObject, the thread that created it runs the message pump that is responsible for processing messages for the foo object. Therefore if that thread ends then the object can no longer process messages, which isn't a good idea.

In most situations you should use the same UI thread to create all of your UI objects (or anything else that is derived from DispatcherObject and make sure it runs for the duration of your application. Then use the Dispatcher to send messages to it from your worker threads.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文