使用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线程。谁能告诉我怎么做到这一点?
感谢。
答案 0 :(得分: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";
}
}
答案 1 :(得分:0)
一个。如果你知道你做了什么,使用多个UI线程没有任何问题。
湾调用UI线程工作者是错误和混乱的 - UI线程#2与#1相同 从开发人员的角度来看。一旦你意识到这一点 - 很多问题都会自行解决。
℃。如果你想从view1 [在UI线程#1中运行]调用view2.SomeMethod()[在UI线程#2中运行] - 在view2上调用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);
}
您将看到线程编号不同但字符串已越过它们。