0

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

4

2 回答 2

3

该类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 代码分开(这是一件非常好的事情)。

于 2013-02-28T19:51:33.373 回答
2

我会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 中的线程的非常好的全面评论:Multi-Threading in .NET。它有一个关于WinForms中的线程的部分,对您有很大帮助。

于 2013-02-28T19:52:33.927 回答