0

我是 Visual C# 的新手,使用 Visual Studio。我有一些在并行 for 循环中完成的计算,我想在这个循环内的输出文本框中输出一些东西(将计算的所有输出保留在屏幕上)。我只是希望能够将文本附加到文本框(或将文本添加到已经存在的文本中)。

我在对 Windows 窗体的线程安全调用中找到了以下链接。他们展示了两个例子,它们都适用于他们提出的案例。他们只是在文本框中显示一条消息。我想将数据附加到文本框。我能够获得以下代码(第一种方式)工作:

    private void setTextSafeBtn_Click(object sender, EventArgs e)
    {
        this.demoThread =
            new Thread(new ThreadStart(this.ThreadProcSafe));
        this.demoThread.Start();
    }


    private void ThreadProcSafe()
    {
        int length = 10;

        Parallel.For(1, length, j =>
        {
            //this.textBox1.Text = this.textBox1.Text + "Simulation Replication " + j.ToString() + "\r\n";
            this.SetText("Simulation Replication " + j.ToString() + "\r\n");
        }); // Parallel.For
     }

    private void SetText(string text)
    {
        if (this.textBox1.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(SetText);
            this.Invoke(d, new object[] { text });
        }
        else
        {
            this.textBox1.Text = this.textBox1.Text + text;
        }
    }

这将产生所需的输出:

模拟复制 4

模拟复制 2

模拟复制 7

...

但是,如果我尝试在并行 for 循环中使用第一行(当前已注释)而不是第二行,则会收到以下错误:

“跨线程操作无效:控件'textBox1'从创建它的线程以外的线程访问。”

第一个问题是,对并行计算不熟悉(在 Matlab 中做过一些)和 Visual C# 的新手,这个错误到底想告诉我什么?还有另一种方法可以完成我想做的事情吗?它比现在有效的方法更容易吗?


现在,我还有另一个问题。我尝试使用为此建议的其他策略,即使用后台工作者,代码非常相似。如果我只显示一条消息而不附加,一切正常。如果我尝试追加,它会进行 5 次并行计算并显示它们,然后 GUI 帮派......只是冻结,没有错误或任何东西,只是卡住了。我使用的代码如下所示(SetText 与上面的代码相同):

    private void setTextBackgroundWorkerBtn_Click(object sender, EventArgs e)
    {
        this.backgroundWorker2.RunWorkerAsync();
    }

    private void backgroundWorker2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        int length = 10;

        Parallel.For(1, length, k =>
        {
            //this.textBox1.Text = this.textBox1.Text + "Simulation Replication " + k.ToString() + "\r\n";
            this.SetText("Simulation Replication " + k.ToString() + "\r\n");

        }); // Parallel.For

    }

它实际上输出前 5 个文本,索引为 1、2、4、6、8。这些都在严格增加的事实有什么关系吗?

我想了解为什么此代码在上述情况下有效,但似乎使用后台工作人员搞砸了。我读到使用后台工作人员是更好的方法。有人可以告诉我一种使用后台工作人员获得所需行为的方法吗?

最后,我实际上只是想知道最好的方法是什么。如果我正在执行一个包含许多计算的并行 for 循环(比如一次迭代的所有计算大约需要 5 秒),并且我想在迭代开始时显示当前索引号,那么最好的方法是什么在并行for循环中?我想在进行这些并行计算之前保留文本框中的所有数据......因此需要附加......

在这里的任何帮助或建议将不胜感激。只需告诉它在控制台应用程序中将一些输出写入控制台很容易,这没问题(同时使用 Matlab 和 C#)。使用文本框似乎会产生问题。请帮忙!

4

0 回答 0