让主线程再次运行?
嗨,
我有一个托管 WCF 服务(NamedPipes)的 winform 应用程序。当接到电话时,将触发一个事件,然后创建并打开一个表单。问题是
ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated because the current thread is not in a single-threaded apartment.
在 winforms InitializeComponent 方法中创建 System.Windows.Forms.WebBrowser 时出现以下异常?
我假设另一个线程正在运行事件(工作线程),我怎样才能让主线程运行该事件?
我当时没有打开任何 winform,因此无法使用 InvokeRequired。
BestRegards
Edit1:请不要我正在使用
[STAThread]
public static void Main(string[] args)
{
Application.Run(_instance);
}
Hi,
I have a winform application that is hosting a WCF Service(NamedPipes). When reciving a call a event will be triggered and then a form will be created and opened. The problem is that I get the followin exception
ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated because the current thread is not in a single-threaded apartment.
When creating a System.Windows.Forms.WebBrowser in the winforms InitializeComponent method?
I Supose that another thread is running the even(working thread), how can I get the main thread to run the event?
I do not have any winform open at the time so I can´t use InvokeRequired.
BestRegards
Edit1 : Pleas not that I am using
[STAThread]
public static void Main(string[] args)
{
Application.Run(_instance);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这些类型的调用是在线程池线程上进行的。它们不适合显示任何 UI。您需要创建自己的正确风格的线程:
您还会遇到其他实际问题,您不能在没有用户参与的情况下弹出一个窗口。典型的事故是用户在没有看到它的情况下意外关闭它,或者窗口消失在用户正在使用的窗口后面。如果您已有用户界面,请务必使用 Control.BeginInvoke() 让主线程显示窗口。考虑使用 NotifyIcon 进行软触摸,在托盘通知区域中显示气球以提醒用户。
These kind of calls are made on thread pool threads. They are not suitable to display any UI. You'll need to create your own thread of the right flavor:
There are other practical problems you'll be battling with this, you can't just pop up a window without the user participating. Typical mishaps are the user accidentally closing it without even seeing it or the window disappearing behind the window that the user is working with. If you already have a user interface then be sure to use Control.BeginInvoke() to let the main thread display the window. Consider the soft touch with a NotifyIcon, displaying a balloon in the tray notification area to alert the user.
该 WCF 调用很可能来自主 UI 线程以外的线程。所有 UI 控件(包括 ActiveX 控件)都必须从 UI 线程且只能从 UI 线程创建和访问。您收到的错误表明创建线程甚至不在单线程单元(STA)中,这也是一个要求。
要让代码在主 UI 线程上执行,请使用
Control.Invoke
方法。它将把委托的执行编组到托管目标Control
或Form
的线程上。如果您没有立即可用的
Control
或Form
引用,那么您需要创建一个。您可能还必须创建一个运行消息循环的线程。这可以通过Application.Run
来完成。创建一个可用于调用Invoke
的隐藏Form
非常简单。它可能是这样的。
That WCF call is most likely coming in on a thread other than the main UI thread. All UI controls including ActiveX ones must be created and accessed from the UI thread and only the UI thread. The error you are getting is indicating that the creating thread is not even in a Single Thread Apartment (STA) which is also a requirement.
To get the code executing on the main UI thread use the
Control.Invoke
method. It will marshal the execution of a delegate onto the thread hosting the targetControl
orForm
.If you do not have a reference to a
Control
orForm
immediately available then you will need to create one. You may have to create a thread that runs a message loop as well. This can be done withApplication.Run
. It is simple enough to create a hiddenForm
that could be used to callInvoke
.Here is what it might look like.
我的解决方案是在启动时创建一个虚拟 winform,当我需要主 UI 线程时,我将在此虚拟表单上使用 invoke。
它将使用更多资源,但我没有看到更简单的方法。
My solution is to create a dummy winform on startup and when I need the main UI thread I will use invoke on this dummyform.
It will use some more resourse but I dont see a simpler way of doing it.