2011-09-21 94 views
0

嗨,获取mainThread再次运行?

我有一个托管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?

我认为另一个线程正在运行even(工作线程),我怎样才能让主线程运行事件?

我没有任何打开的winform,所以我不能使用InvokeRequired。

BestRegards

EDIT1:普莱斯不,我使用

[STAThread] 
public static void Main(string[] args) 
{ 
Application.Run(_instance); 
} 

回答

0

我的解决方案是在启动时创建一个虚拟winform,当我需要主UI线程时,我将在此虚拟表单上使用invoke。

它会使用更多的资源,但我没有看到一个更简单的方法。

0

这WCF调用最有可能即将在比主UI线程的线程上。所有UI控件(包括ActiveX控件)必须通过UI线程创建和访问,并且只能通过UI线程访问。你得到的错误是指出创建线程甚至不在单线程公寓(STA)中,这也是一个要求。

要获得在主UI线程上执行的代码,请使用Control.Invoke方法。它会将代理的执行管理到托管目标ControlForm的线程上。

如果您没有提及立即可用的ControlForm,那么您将需要创建一个。您可能必须创建一个运行消息循环的线程。这可以通过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(/* ... */); 
} 
+0

但是,如果我在当前线程池线程上创建窗体或控件,winform是否不会绑定到此线程?我听说创建窗体/控件的线程必须是更新窗体/控件的线程?或者当创建新的表单/控件并执行工作时,主UI线程会进入吗?你能否提供一个小例子? – Banshee

+0

@SnowJim:我更新了我的答案。你将不得不手动创建一个UI线程。 –

+0

谢谢,但如果应用程序在主UI线程上运行其他部分(使用Application.Run),这将会很奇怪。我可不能简单地将当前的UI线程在启动时存储在属性中,然后使用此线程触发事件? – Banshee

1

这些类型的调用是在线程池线程上进行的。它们不适合显示任何UI。你需要创建的对味自己的线程:

 var t = new Thread(() => { 
      Application.Run(new Form1()); 
     }); 
     t.SetApartmentState(ApartmentState.STA); 
     t.Start(); 

有你这个被争夺等实际问题,你不能只是弹出一个窗口,而不参与用户。典型的意外事故是用户意外关闭它,甚至没有看到它,或者窗户在用户正在使用的窗户后面消失。如果你已经有一个用户界面,那么一定要使用Control.BeginInvoke()让主线程显示窗口。考虑用NotifyIcon轻触,在托盘通知区域显示气球以提醒用户。

+0

谢谢,但主UI线程在哪里?我应该不使用该线程吗? – Banshee

+0

@SnowJim:和我一样,我怀疑汉斯还假定没有UI线程存在。 –

+0

抱歉不清楚。应用程序将以[STAThread] public static void Main(string [] args)开头,然后是Application.Run(_instance);.我认为这将意味着一个UI线程将被创建(messagepump)。到目前为止,我的解决方案是在启动时以及需要UI线程时创建一个dummyForm(从未显示)。Invoke将用于此虚拟表单。坏/神? – Banshee

相关问题