Reputation: 3252
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.?
Upvotes: 2
Views: 777
Reputation: 11457
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.
Upvotes: 1
Reputation: 755179
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.
Upvotes: 1
Reputation: 1644
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).
Upvotes: 2