2009-04-24 135 views
6

如何强制一段代码在我的主线程上执行?在主线程上强制执行代码

这就是为什么我想知道:

我有时常会从一个线程是不是主线程显示自定义创建的消息框。但是,当消息框构造函数被调用时,我得到一个InvalidOperationException异常,说“调用线程必须是STA,因为许多UI组件需要这个。”这是有道理的,UI元素需要在主线程上处理。

My MessageBox.ShowMessage(...)函数是一个静态函数,它创建自定义消息框的实例并显示它。有什么我可以放在ShowMessage中强制消息框被创建并显示在主线程上?在我的代码中的其他地方,我使用Control.BeginInvoke来处理类似的问题,但由于它是一个静态函数,因此我没有现有的UI元素来调用BeginInvoke。

是否必须使用Control.BeginInvoke调用MessageBox.ShowMessage?我更喜欢在ShowMessage中调用BeginInvoke(或一些等价的)。

回答

5

有几个选择这里:

  • 使第二个线程STA(你只能为自己的Thread做到这一点 - 为ThreadPool线程不) - 通过.SetApartmentState(ApartmentState.STA);
  • 看看SynchronizationContext.Current是非空值;如果是这样,使用Send/Post
  • 在通过窗体/控件作为ISynchronizeInvoke实例(可能并不适用于WPF - 我不是100%确定)
+0

您是否有链接解释如何执行您列出的第一个选项? – w4g3n3r 2009-04-24 21:41:02

+0

在启动线程之前调用Thread.SetApartmentState()。 – itowlson 2009-04-24 21:44:08

+0

创建线程时,只需调用。(编辑)答案中显示的.SetApartmentState。首先让我知道是否需要更多帮助来创建线程。 – 2009-04-24 21:44:25

5

你的想法是正确的 - 为了让它正常工作,你将需要从主线程调用它。

最简单的方法?当您启动主窗体时,将引用保存在ShowMessage()调用可见的静态变量中。然后,你可以ShowMessage做标准:

if(myForm.InvokeRequired) 
{ 
    myForm.Invoke(() => ShowMessage(arg1,arg2,arg3)); 
    return; 
} 
.... other code here.... 
1

,而不是直接显示在消息框中,只是将消息发送到你的主线程,这标志着主线程显示一个消息框。