我在使用多线程时遇到了一个非常烦人的问题,我只是在这样的循环中用多行更新一个textBox:
if (results.Lines.Count() != 0)
this.InvokeEx(f => f.results.Text += Environment.NewLine);
this.InvokeEx(f => f.results.AppendText("0\t1"));
当我只使用一个线程运行时,所有看起来都没问题:
但是当我使用多线程(同时10个线程)运行时:
看起来textBox中的写入不是同步的,一切看起来都搞砸了。
有什么方法可以解决这个问题吗?
使用带有.Net Framework 4的Windows窗体应用程序。
提前致谢。
答案 0 :(得分:4)
那是因为刚刚写了一个新行的线程可能被另一个线程抢占了另一个新行。
您应确保将您的两条指令视为原子操作。即,多个并发操作将被视为顺序操作。
您可以在关键区域周围引入lock。
private readonly object _lock = new object();
lock(_lock)
{
if (results.Lines.Count() != 0)
this.InvokeEx(f => f.results.Text += Environment.NewLine);
this.InvokeEx(f => f.results.AppendText("0\t1"));
}
答案 1 :(得分:1)
您希望将带有附加文本的新行附加为原子操作。目前,您绝不会强制执行这两个操作以原子方式执行的约束,即使您依赖它。最简单的解决方案是简单地调用Invoke
一次,并在执行此操作之前构建字符串:
string textToAppend = ConstructStringToAppend();
this.InvokeEx(f => f.results.AppendText(textToAppend));
现在您知道该字符串将被写为一个原子操作。
答案 2 :(得分:1)
你可以不用每次都检查行数并将其压缩成一行:
this.InvokeEx(
f => f.results.AppendText(string.Concat("0\t1", Environment.NewLine)));