【问题标题】:Create a Windows Form from a background Thread从后台线程创建 Windows 窗体
【发布时间】:2011-05-24 10:38:50
【问题描述】:

我正在开发一个 VS 包,我遇到了这个问题:

我有一个后台线程,它每隔几秒钟检查一次必须完成的特定更改。这包括更改 VS 2010 的 GUI,由于某种原因,它无需调用即可正常工作。

无论如何,如果我尝试打开一个新表单,它会打开,但它没有显示任何内容,有点崩溃并且没有响应。
我已经尝试过Application.OpenForms[0].invoke( /* delegate to create the form */)
这很好用,但我并没有一直打开表单
我也尝试过创建一个 System.Windows.Forms.Timer,但它一开始就没有启动

问题:如何获得正确的 GUI 线程来调用我的表单?
或者更确切地说:如何从我的后台线程创建一个新表单?

【问题讨论】:

    标签: c# winforms multithreading thread-safety


    【解决方案1】:

    在您的主应用程序启动时将 SynchronizationContext.Current 的实例存储在某处。 一旦设置。 您可以在任何其他线程中尝试以下代码。

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

    其中 GuiContext 是 SynContext 的存储实例。

    【讨论】:

    • 完美,非常感谢!我试过Application.Run(/*create form*/),但不幸的是这个阻塞了。我不得不稍微修改你的答案,因为否则我无法编译。我的解决方案是:syncContext.Send(delegate(object someState) { /*create form*/ }, null); 并且效果很好。
    【解决方案2】:

    在没有任何全局变量的情况下执行此操作的另一种方法是(对 VB.NET 感到抱歉 - 在 VB.NET 中执行此操作):

     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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-30
      • 1970-01-01
      • 2014-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多