Jay
Jay

Reputation: 89

Exception: The Calling thread cannot access this object because a different thread owns it

I'm converting a UI from windows forms to WPF. I'm getting the following exception "The Calling thread cannot access this object because a different thread owns it" whenever I try to call anything on this new WPF window I created.

I referred stack overflow and many websites to find out that I should use Dispatcher.CheckAccess() or somethings similar to dispatcher and check access. I tried many such things

This is one of the things that I have used

Private Delegate Sub ShowSkinInvoked()

If (Dispatcher.CheckAccess()) Then
    Me.Show()
Else
    Dim d As ShowSkinInvoked = New ShowSkinInvoked(AddressOf ShowSkin)
    Dispatcher.Invoke(d)
End If

This has removed the exception and while debugging the error is gone but it freezes the application and I cannot do anything other than terminate it. It doesn't even show the window after "Me.Show".

Also, if I compile the program and then make the calling module use this compiled exe by specifying path to exe then for some reason it works perfect.

If this sounds confusing then what I mean is, I have multiple forms. If I call the code in module A to load and display module B then it gives me the exception but if I call the code in module A to run the compiled exe of module B then it runs perfectly.

Any suggestions?

Upvotes: 1

Views: 1201

Answers (1)

dave
dave

Reputation: 185

When WPF creates a user interface it created a thread that is responsible for handling all the user interaction events and scheduling the rendering. This is called the dispatcher thread. Many of the objects that it creates are sub classes of DispatcherObject.

You can't call methods on a DispatcherObject from threads other then the Dispatcher thread that created them. The reasons why are complicated but relate to COM interop.

When you are in a Buttons click event you are running on dispatcher thread.

If you are coming from another thread you must get your work to be performed on the dispatcher thread. It can typically be found by accessing the static current dispatcher Dispatcher.CurrentDispatcher, unless your creating multiple dispatcher threads.

However I would suggest explaining your problem in terms of what work your trying to do with regards to having one form show ui on another. There are multiple ways like an EventAggregator to communicate between ui that might be more appropriate.

Upvotes: 2

Related Questions