【问题标题】:Cross-threading the hide method跨线程 hide 方法
【发布时间】:2013-06-26 20:17:31
【问题描述】:

我试图从辅助线程隐藏在主线程上创建的表单,但是当我调用 hide 方法时,我显然遇到了跨线程问题。我是新手,对于如何纠正这个问题并没有真正的线索。我总是创建一个委托来调用我的方法,如果它正在更改在主线程上创建的东西,但我不知道如何在这里为内置的 hide 方法执行此操作。如果您需要更多信息,请告诉我。

代码:

public partial class MainForm : Form
{
    ControlPanelForm m_controlPanel = new ControlPanelForm();
    // ....
    void MeterThread()
    {
        while (true)
        {
            // ....
            if (EMOdetected)
            {
                m_controlPanel.Deinitialize();                    
                m_controlPanel.Hide();         // **** //
            }
        }
    }
}

基本上,我的 MainForm 会拉出一个控制面板表单来完成一些工作。在后台我有一个线程正在运行并检查东西,其中一个是紧急关闭,此时我想关闭我的控制面板然后隐藏它。

如果我尝试在那里调用它,

m_controlPanel.Invoke(new EMOHandler(m_controlPanel.Hide));    // **** //

当我调试它时,它看起来并没有执行任何操作。它似乎只是传递了命令。再说一次,我是新手,所以欢迎任何和所有的解释。

【问题讨论】:

    标签: c# multithreading


    【解决方案1】:

    您没有提供任何代码方面的信息,但这是从非 UI 线程操作 UI 线程的常见模式。

    if (mainForm.InvokeRequired)
    {
        mainForm.Invoke(new Action(() =>
        {
           mainForm.Hide();
        }));
    }
    else    
        mainForm.Hide();
    

    【讨论】:

      【解决方案2】:

      作为一个简单的规则,您已经指出: 您不应从另一个线程访问一个窗口。

      我建议你这样做:

      public partial class Form1 : Form
      {
          public Form1()
          {
              InitializeComponent();
              new Thread(SampleFunction).Start();
          }
      
          public void AppendTextBox(string value)
          {
              if (InvokeRequired)
              {
                  this.Invoke(new Action<string>(AppendTextBox), new object[] {value});
                  return;
              }
              textBox1.Text += value;
          }
      
          void SampleFunction()
          {
              // Gets executed on a seperate thread and 
              // doesn't block the UI while sleeping
              for(int i = 0; i<5; i++)
              {
                  AppendTextBox("hi.  ");
                  Thead.Sleep(1000);
              }
          }
      }
      

      这是我从here 获得的关于如何使用多线程的一个非常好的示例。

      尽管在您的情况下,方法 Hide 已经存在于 MainForm 上,并且确实在等待您被调用,就像其他人已经指出的那样:

      mainForm.Invoke(new MethodInvoker(mainForm.Hide));
      

      【讨论】:

        【解决方案3】:

        没有理由检查InvokeRequired 或创建匿名方法。简单写

        mainForm.Invoke(new MethodInvoker(mainForm.Hide));
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-01-15
          • 1970-01-01
          • 2019-10-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-08-15
          相关资源
          最近更新 更多