从另一个类和线程添加到文本框

本文关键字:文本 添加 线程 另一个 | 更新日期: 2023-09-27 18:01:33

我有一个设置和显示文本框的表单。在表单加载方法中,我从一个完全独立的类名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线程,而不是从单独的类。

从另一个类和线程添加到文本框

Progress类就是为此专门设计的。

在你的表单中,在启动后台线程之前,创建一个Progress对象:
Progress<string> progress = new Progress<string>(text => textbox.Text += text);

然后提供progress对象给你的工作方法:

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代码都在表单的定义内,所有的非UI代码都在表单之外,帮助将业务代码与UI代码分开(这是一件非常好的事情)。

我会添加一个AppendText()方法到您的Form1类,像这样:

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中线程的一个非常全面的回顾:。net中的多线程。它有一个关于WinForms中的线程的章节,会对你有很大的帮助。