我是Visual C#的新手,使用Visual Studio。我有一些在并行for循环中完成的计算,我想输出一些东西到这个循环中的输出文本框(保持屏幕上计算的所有输出)。我只是希望能够将文本附加到文本框中(或将文本添加到已存在的文本中)。
我在Windows窗体的线程安全调用中找到了以下link。他们展示了两个例子,都适用于他们提出的案例。他们只是在文本框中显示一条消息。我想将数据附加到文本框中。我能够得到以下代码(第一种方式):
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#)。使用文本框似乎会产生问题。请帮助!