从 UI 线程调用工作线程上的方法
本文关键字:线程 方法 调用 UI 工作 | 更新日期: 2023-09-27 17:56:28
使用
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 线程调用工作线程上的方法。 谁能告诉我我该怎么做?
谢谢。
在极少数情况下,运行多个 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";
}
}
a. 如果您知道自己在做什么,那么使用多个 UI 线程并没有错。
b. 调用 UI 线程工作线程是不正确的和令人困惑的 - UI 线程 #2 与 #1 相同从开发人员的角度来看。一旦你意识到这一点 - 许多问题就会自行解决。
c. 如果要调用 view2。SomeMethod() [在 UI 线程 #2 中运行] 从 view1 [在 UI 线程 #1 中运行] - 在视图 2 上调用 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);
}
您将看到线程编号不同,但字符串已正常交叉它们。