C# 从后台线程创建Windows窗体

C# 从后台线程创建Windows窗体,c#,winforms,multithreading,thread-safety,C#,Winforms,Multithreading,Thread Safety,我正在开发一个VS软件包,我遇到了以下问题: 我有一个后台线程,每隔几秒钟检查一次必须进行的特定更改。这包括更改VS 2010的GUI,由于某种原因,VS 2010在没有调用的情况下运行良好 不管怎样,如果我尝试打开一个新表单,它会打开,但不会显示任何内容,有点崩溃,也没有响应。 我已经尝试了应用程序。OpenForms[0]。调用(/*委托以创建表单*/) 这很好,但我不是一直都有一个开放的表单 我还尝试创建System.Windows.Forms.Timer,但它一开始没有启动 问题:如何获

我正在开发一个VS软件包,我遇到了以下问题:

我有一个后台线程,每隔几秒钟检查一次必须进行的特定更改。这包括更改VS 2010的GUI,由于某种原因,VS 2010在没有调用的情况下运行良好

不管怎样,如果我尝试打开一个新表单,它会打开,但不会显示任何内容,有点崩溃,也没有响应。
我已经尝试了
应用程序。OpenForms[0]。调用(/*委托以创建表单*/)

这很好,但我不是一直都有一个开放的表单
我还尝试创建System.Windows.Forms.Timer,但它一开始没有启动

问题:如何获得正确的GUI线程来调用表单?

或者更确切地说:如何从我的后台线程创建一个新表单?

存储SynchronizationContext的实例。当主应用程序启动时,它是当前的。 一旦成立。 您可以在任何其他线程中尝试以下代码

 GuiContext.Send(_ => {
                        Form2 frm2=new Form2();
                        frm2.ShowDialog();
                       }, null);

其中,GuiContext是SynContext的存储实例。

不使用任何全局变量的另一种方法是(很抱歉,VB.NET是在VB.NET中执行此操作的):

Dim结果作为对象
Dim deleg为ThreadStart=Sub()结果=DoSomethingHere()
如果是Thread.CurrentThread.GetApartmentState ApartmentState.STA,则
尺寸t为新螺纹(deleg)
t、 SetApartmentState(ApartmentState.STA)'将线程设置为STA
t、 开始()
t、 Join()'等待线程结束
其他的
deleg.Invoke()
如果结束

太好了,非常感谢!我尝试了
Application.Run(/*createform*/)
,但不幸的是,这会阻塞。我不得不稍微修改一下你的答案,因为我无法编译其他答案。我的解决方案是:
syncContext.Send(委托(对象someState){/*创建表单*/},null)和工作完美。
 Dim result as Object
 Dim deleg As ThreadStart = Sub() result = DoSomethingHere()
 If Thread.CurrentThread.GetApartmentState <> ApartmentState.STA Then
 Dim t As New Thread(deleg)
     t.SetApartmentState(ApartmentState.STA) 'Set the thread to STA
     t.Start()
     t.Join() 'Wait for the thread to end
 Else
     deleg.Invoke()
 End If