如何从运行不同类的新线程更新主线程中的文本框和标签。
MainForm.cs(主线程)
public partial class MainForm : Form
{
public MainForm()
{
Test t = new Test();
Thread testThread = new Thread(new ThreadStart(t.HelloWorld));
testThread.IsBackground = true;
testThread.Start();
}
private void UpdateTextBox(string text)
{
textBox1.AppendText(text + "\r\n");
}
}
public class Test
{
public void HelloWorld()
{
MainForm.UpdateTextBox("Hello World");
// How do I execute this on the main thread ???
}
}
我看过这里的例子,但似乎无法做到正确。请有人给一些好的链接。
我已经重新开始,所以我不会搞砸我的代码。如果有人想用我的例子提出一个很好的例子。
此外,如果我不得不更新多个对象,如文本框和标签等(不是所有的同时),最好的方法是什么,为每个文本框设置一个方法,或者有办法做到这一点一种方法?
答案 0 :(得分:6)
Invoke或BeginInvoke,例如
Invoke((MethodInvoker)delegate {
MainForm.UpdateTextBox("Hello World");
});
@tiptopjones我想你也在问如何获得对表单的引用。您可以使HelloWorld方法获取对象参数,使用ParameterizedThreadStart委托,然后将对表单的引用作为参数传递给Thread.Start方法。但我建议阅读有关匿名方法的内容,这些方法可以让它变得更容易,并且可以保存所有强类型内容。
public class MainForm : Form {
public MainForm() {
Test t = new Test();
Thread testThread = new Thread((ThreadStart)delegate { t.HelloWorld(this); });
testThread.IsBackground = true;
testThread.Start();
}
public void UpdateTextBox(string text) {
Invoke((MethodInvoker)delegate {
textBox1.AppendText(text + "\r\n");
});
}
}
public class Test {
public void HelloWorld(MainForm form) {
form.UpdateTextBox("Hello World");
}
}
当你对此感到满意时,你可以阅读lambda表达式并按照:
进行操作Thread testThread = new Thread(() => t.HelloWorld(this));
答案 1 :(得分:4)
您可以调用BeginInvoke
method,它将队列一个委托在UI线程上异步执行。
如果你需要后台线程等到UI线程上的函数完成,你可以改为调用Invoke
。
请注意,您需要对表单实例的引用;您应该将其传递给Test
构造函数并将其存储在私有字段中。
BackgroundWorker component将使用ReportProgress
方法自动完成所有这些操作;你应该考虑使用它。
答案 2 :(得分:1)
WinForms中的首选方法是使用SynchronizationContext
public partial class MainForm : Form
{
SynchronizationContext ctx;
public MainForm()
{
ctx = SynchronizationContext.Current;
Test t = new Test();
Thread testThread = new Thread(new ThreadStart(t.HelloWorld));
testThread.IsBackground = true;
testThread.Start();
}
private void UpdateTextBox(string text)
{
ctx.Send(delegate(object state)
{
textBox1.AppendText(text + "\r\n");
},null);
}
}
public class Test
{
public void HelloWorld()
{
MainForm.UpdateTextBox("Hello World");
// How do I excute this on the main thread ???
}
}