Hi,
我有一个winform应用程序,它承载一个WCF (NamedPipes)。当接收到调用时,将触发事件,然后创建并打开表单。问题是我得到了下面的例外
ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated because the current thread is not in a single-threaded apartment.当在winforms System.Windows.Forms.WebBrowser方法中创建InitializeComponent时?
我假设另一个线程正在运行偶数(工作线程),如何使主线程运行该事件?
当时我没有打开任何winform,所以我不能使用InvokeRequired。
BestRegards
Edit1 :请不要说我在用
[STAThread]
public static void Main(string[] args)
{
Application.Run(_instance);
}发布于 2011-10-04 09:24:39
我的解决方案是在启动时创建一个虚拟winform,当我需要主UI线程时,我将在这个虚拟表单上使用invoke。
它会使用更多的资源,但我看不出有更简单的方法。
发布于 2011-09-21 16:49:28
这类调用是对线程池线程进行的。它们不适合显示任何UI。您需要创建自己的线程,并具有正确的风格:
var t = new Thread(() => {
Application.Run(new Form1());
});
t.SetApartmentState(ApartmentState.STA);
t.Start();还有其他一些实际问题,你不能在没有用户参与的情况下弹出一个窗口。典型的事故是用户意外地关闭了它,甚至没有看到它,或者用户正在使用的窗口后面的窗口消失了。如果您已经有了一个用户界面,那么一定要使用Control.BeginInvoke()让主线程显示窗口。考虑使用NotifyIcon进行软触摸,在托盘通知区域显示一个气球,以提醒用户。
发布于 2011-09-21 16:09:59
WCF调用很可能出现在主UI线程之外的线程上。所有UI控件(包括ActiveX控件)都必须从UI线程中创建和访问,而只有UI线程。您所得到的错误指示创建线程甚至不在单个线程单元(STA)中,这也是一个要求。
要在主UI线程上执行代码,请使用Control.Invoke方法。它将将委托的执行封送到承载目标Control或Form的线程上。
如果您没有立即可用的Control或Form引用,则需要创建一个引用。您可能还必须创建一个运行消息循环的线程。这可以用Application.Run来完成。创建一个隐藏的Form非常简单,可以用来调用Invoke。
下面是它的样子。
void SomeMethodExecutingOnThreadPool()
{
var form = null;
var mre = new ManualResetEvent(false);
// Create the UI thread.
new Thread(
() =>
{
form = new Form();
form.Load +=
(sender, args) =>
{
mre.Set();
}
Application.Run(form);
}).Start();
// Wait for the UI thread to initialize.
mre.WaitOne();
// You can now call Invoke.
form.Invoke(/* ... */);
}https://stackoverflow.com/questions/7501564
复制相似问题