Click here to Skip to main content
15,861,168 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
While I was trying to add Controls to my UserControl list it threw "The calling thread cannot access this object because a different thread owns it." exception.


panel_PanelHolder.Children.Clear();
panel_PanelHolder.Children.Add(usr_panel);



But when I used below code,

Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
panel_PanelHolder.Children.Clear();
panel_PanelHolder.Children.Add(usr_panel);
}));


It throws "Exception has been thrown by the target of an invocation." exception.
What I need is to clear controls, and add a control to the panel. I'm not sure how to fix this ASAP. I'm using a STA thread to manipulate WPF window controls dynamically. Can someone help me on this?
Thanks
Posted

1 solution

First exception was related to the fact that you could not really do any call related to UI in some thread other than the UI thread using those UI elements. Your use of the Dispatcher is quite correct, except one detail: most likely, you need to use Dispatcher.Invoke instead of Dispatcher.BeginInvoke (why? you are not returning anything). This cannot be a reason for your problem though.

The only problem is just the cryptic way Visual Studio shows the exception if it is thrown in the invocation situation, nothing else. It means, there is a "real" exception in the thread where it was originally thrown, but it is not shown, only the secondary exception in the invoking thread is shown. (However, look at Exception.InnerException under the debugger; I just don't clearly remember if it is used in such cases or not.)

All you need is just a little better way to debug it. For example, if you are really sure that the exception is thrown in the invoked anonymous method shown in your question (you can check it up my commenting these two lines out and trying again), you could write these two lines under try-catch block, put your breakpoint in the catch part and examine the exception caught.

Another approach (in more complex situations; and this one is, in fact, pretty simple) would be using System.Diagnostics.EventLog:
http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog.aspx[^].

Possible reasons for exception could be: 1) panel_PanelHolder.Children is null; 2) usr_panel is invalid; it could be null or already uses as a child in some other UIElement (one unique feature of WPF is that such cases are cracked down). I am not sure though; you will find out when you perform more informative debugging.

[EDIT]

By the way, WPF really requires STA model for the initial thread starting the UI, but for other threads, it is not really required. If you want, you can create a MTA thread and use it in your WPF application.

This is very important: there are some other APIs which can work in MTA thread only or in STA thread only. If MTA is required, how can you use them in WPF?

I faced with such situation with System.Speech.Recognition: one of the two recognizer classes requires STA, another one requires MTA. The WPF workaround was to create some other thread and make it MTA. It just works. (And System.Windows.Forms application's main thread can be either STA or MTA.)

Good luck,
—SA
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900