WPF应用程序异常:调用线程无法访问此对象,因为另一个线程拥有它 [英] WPF Application Exception: The calling thread cannot access this object because a different thread owns it

查看:119
本文介绍了WPF应用程序异常:调用线程无法访问此对象,因为另一个线程拥有它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我试图将控件添加到我的UserControl列表时,它抛出调用线程无法访问此对象,因为另一个线程拥有它。例外。





panel_PanelHolder.Children.Clear();

panel_PanelHolder.Children.Add(usr_panel) ;







但是当我使用下面的代码时,



Dispatcher.BeginInvoke(DispatcherPriority.Background,new Action(()=>

{

panel_PanelHolder.Children.Clear();

panel_PanelHolder.Children.Add(usr_panel);

}));





它抛出调用目标引发了异常。例外。

我需要的是清除控件,并向面板添加一个控件。我不确定如何尽快解决这个问题。我正在使用STA线程动态操作WPF窗口控件。有人可以帮我吗?

谢谢

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

推荐答案

第一个异常与以下事实有关:在某些线程中你无法真正做任何与UI相关的调用UI线程使用这些UI元素。您对Dispatcher的使用非常正确,除了一个细节:您很可能需要使用 Dispatcher.Invoke 而不是 Dispatcher.BeginInvoke (为什么?你没有返回任何东西)。这可能不是你问题的原因。


唯一的问题就是隐藏的方式Visual Studio显示异常如果它被抛出在调用情况下,没有别的。这意味着,在最初抛出它的线程中存在一个真实异常,但是没有显示,只显示了调用线程中的二级异常。 (但是,请查看调试器下的 Exception.InnerException ;我只是不清楚是否在这种情况下使用它。)



您只需要一个更好的调试方法。例如,如果您确实在您的问题中显示的调用匿名方法中抛出了异常(您可以检查一下我将这两行注释掉并再次尝试),您可以在try-catch块下写下这两行,将你的断点放在catch部分并检查捕获的异常。



另一种方法(在更复杂的情况下;事实上,这个非常简单)使用 System.Diagnostics.EventLog

http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog.aspx [ ^ ]。



例外的可能原因可能是:1) panel_PanelHolder.Children 为空; 2) usr_panel 无效;它可能为null或已经在其他一些 UIElement 中用作子项(WPF的一个独特功能是此类案例被破解)。我不确定;当你进行更多信息调试时,你会发现。







顺便说一下, WPF确实需要STA模型用于启动UI的初始线程,但对于其他线程,它并不是真正需要的。如果需要,可以创建一个MTA线程并在WPF应用程序中使用它。



这非常重要:还有一些其他API可以在MTA线程中使用仅限于或仅在STA线程中。如果需要MTA,你如何在WPF中使用它们?



我遇到了这种情况 System.Speech.Recognition :两个识别器类中的一个需要STA,另一个需要MTA。 WPF的解决方法是创建一些其他线程并使其成为MTA。它只是有效。 (并且 System.Windows.Forms 应用程序'的主线程可以是STA或MTA。)



祝你好运,

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



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


这篇关于WPF应用程序异常:调用线程无法访问此对象,因为另一个线程拥有它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆