0

使用 C# 在 Winforms 中工作,我有一个主窗体,它在单独的线程上创建第二个 UI 窗体。

viewThread = new Thread( ( ) => 
{ 
  views = new Views.Views( displayRotators, screenLocationLeft, screenLocationTop, screenHeight, screenWidth );
  Application.Run( views );
} );
viewThread.SetApartmentState( ApartmentState.STA );
viewThread.Start( );

在第二个 UI 表单上,我现在需要调用一个方法来启动一个显示循环,该循环将一直运行到我终止线程为止。我花了大约三个小时试图找到一种方法来做到这一点,但我能找到的只是从工作线程调用主 UI 线程上的方法的示例,而不是从主 UI 线程调用工作线程上的方法。谁能告诉我我该怎么做?

谢谢。

4

2 回答 2

3

很少有运行多个 UI 线程真正有意义的情况。除非您有非常令人信服的理由这样做,否则我会回到单个 UI 线程。

假设您必须有多个 UI 线程,黄金法则是控件只能从创建它们的 UI 线程更新。. 如果您想调用一般方法,则根本不必编组它们。但是,如果这些方法又与 UI 控件交互,则您只需将调用与来自任何其他线程(不是属于该控件的 UI 线程)的调用完全相同的方式编组该调用。

如果你可能有类似的东西

btnOnForm1OnUIThread1_Click(...)
{
    UpdateForm2OnUIThread2();
}

UpdateForm2OnUIThread2()
{
    if (control.InvokeRequired)
    {
      // Syntax of this line may be slightly off as I'm writing from memory ... 
      // I normally use an extension method
      control.Invoke(UpdateForm2OnUIThread2); 
    }
    else
    {
      control.Text = "Blah";
    }    
}
于 2013-01-28T21:03:21.650 回答
0

一个。如果您知道自己在做什么,那么使用多个 UI 线程并没有错。

湾。调用 UI 线程工作者是不正确且令人困惑的 - 从开发人员的角度来看,UI 线程 #2 与 #1 相同。一旦你意识到这一点 - 许多问题都会自行解决。

C。如果您想从 view1 [在 UI 线程 #1 中运行] 调用 view2.SomeMethod() [在 UI 线程 #2 中运行] - 在 vi​​ew2 上调用 BeginInvoke。

下面的代码很容易采用。button1 - 启动第二个 UI 线程。button2 - 在 UI 线程 2 中的表单上从 UI 线程 1 调用方法

    Form2 form;
    private void button1_Click(object sender, EventArgs e)
    {
        Thread viewThread = new Thread(() =>
        {
            form = new Form2();
            Application.Run(form);
        });
        viewThread.SetApartmentState(ApartmentState.STA);
        viewThread.Start();

        label1.Text = Thread.CurrentThread.ManagedThreadId.ToString();

    }

    private void button2_Click(object sender, EventArgs e)
    {
        if (form != null)
        {
            form.BeginInvoke(new Action(() => 
                {form.Method("Form1 is calling...");}));
        }
    }

形式 2:

    public void Method(string s)
    {
        label1.Text = string.Format("{0} '{1}'", 
                        Thread.CurrentThread.ManagedThreadId, s);
    }

您会看到线程编号不同,但字符串已通过它们确定。

于 2013-01-31T03:55:06.570 回答