我有一个设置并显示文本框的表单。在表单加载方法中,我从一个完全独立的类名Processing
开始一个新线程:
private void Form1_Load(object sender, EventArgs e)
{
Processing p = new Processing();
Thread processingThread = new Thread(p.run);
processingThread.Start();
}
这是处理类。我想要做的是在Utilities
类中创建一个方法,允许我从我需要的任何类更新文本框:
public class Processing
{
public void run()
{
Utilities u = new Utilities();
for (int i = 0; i < 10; i++)
{
u.updateTextBox("i");
}
}
}
然后是Utilites
类:
class Utilities
{
public void updateTextBox(String text)
{
//Load up the form that is running to update the text box
//Example:
//Form1.textbox.appendTo("text"):
}
}
我已经阅读了Invoke
方法,SynchronizationContext
,后台线程和其他所有内容,但几乎所有示例都使用与Form
线程相同的类中的方法,而不是来自单独的课程。
答案 0 :(得分:3)
Progress
类是专门为此设计的。
在表单中,在启动后台线程之前,创建一个Progress
对象:
Progress<string> progress = new Progress<string>(text => textbox.Text += text);
然后将progress
对象提供给您的worker方法:
Processing p = new Processing();
Thread processingThread = new Thread(() => p.run(progress));
processingThread.Start();
然后处理器可以报告进度:
public class Processing
{
public void run(IProgress<string> progress)
{
for (int i = 0; i < 10; i++)
{
Thread.Sleep(1000);//placeholder for real work
progress.Report("i");
}
}
}
Progress
类在内部将捕获首次创建它的同步上下文,并对由于Report
调用该上下文而调用的所有事件处理程序进行编组,这只是一种奇特的方式说它负责代表你移动到UI线程。它还确保您的所有UI代码都保留在Form的定义内,并将所有非UI代码保留在表单之外,从而帮助将业务代码与UI代码分开(这是一件非常好的事情)。
答案 1 :(得分:2)
我会在Form1类中添加AppendText()
方法,如下所示:
public void AppendText(String text)
{
if (this.InvokeRequired)
{
this.Invoke(new Action<string>(AppendText), new object[] { text });
return;
}
this.Textbox.Text += text;
}
然后从您的实用程序类中调用它:
class Utilities
{
Form form1; // I assume you set this somewhere
public void UpdateTextBox(String text)
{
form1.AppendText(text);
}
}
可以在此处找到有关.NET中线程的非常全面的综述:Multi-Threading in .NET。它有Threading in WinForms部分可以帮助你很多。