C# 从UI线程调用工作线程上的方法
在Winforms中使用C#,我有一个主窗体,可以在单独的线程上创建第二个UI窗体C# 从UI线程调用工作线程上的方法,c#,winforms,multithreading,C#,Winforms,Multithreading,在Winforms中使用C#,我有一个主窗体,可以在单独的线程上创建第二个UI窗体 viewThread = new Thread( ( ) => { views = new Views.Views( displayRotators, screenLocationLeft, screenLocationTop, screenHeight, screenWidth ); Application.Run( views ); } ); viewThread.SetApartmentS
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";
}
}
很少有情况下运行多个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。如果要从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);
}
您将看到线程编号不同,但字符串已穿过它们。OK。a。如果您知道自己在做什么,那么使用多个UI线程没有什么错 b。调用UI线程工作程序是不正确和混乱的-UI线程#2与#1相同 从开发者的立场来看。一旦你意识到这一点,许多问题就会自行解决 c。如果要从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);
}
您将看到线程编号不同,但字符串已穿过它们。请不要为自己创建多个UI线程。您最好始终只使用一个线程。您不能从主线程以外的任何线程修改UI,因此无法执行您的要求。为了您自己的缘故,请不要创建多个UI线程。您最好始终只使用一个线程。您不能从主线程以外的任何线程修改UI,因此无法执行您的要求。好吧,是和否。第二个表单(工作线程)上的方法基本上会永远循环(直到停止),只需一个接一个地公开一系列GroupBox。我试图直接调用“Start”方法,但是由于我启动第二个表单的方式,我得到的是NULL,而不是对表单的引用。我想我遗漏了一些东西。在我提供的原始代码片段中,当我从新的线程函数中出来时,“views”为NULL。我本来希望得到表单的句柄,但我没有,所以我不能像我需要的那样简单地调用views.Start()。好吧,是和否。第二个表单(工作线程)上的方法基本上会永远循环(直到停止),只需一个接一个地公开一系列GroupBox。我试图直接调用“Start”方法,但是由于我启动第二个表单的方式,我得到的是NULL,而不是对表单的引用。我想我遗漏了一些东西。在我提供的原始代码片段中,当我从新的线程函数中出来时,“views”为NULL。我本来希望得到表单的句柄,但我没有,所以我不能像我需要的那样简单地调用views.Start()。