Bob Wintemberg
Bob Wintemberg

Reputation: 3252

InvalidOperationException on object from a thread that's done

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

Answers (3)

GraemeF
GraemeF

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

JaredPar
JaredPar

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

helios456
helios456

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

Related Questions