我正在使用同时运行的5个BackgroundWorker对象用于特定目的,并且所有这些对象都必须更改相同的标签。我该怎么做?
如何从多个线程修改表单呢?如果我想更改公共字符串,我该怎么做呢?
答案 0 :(得分:17)
将Control.Invoke与委托一起使用。
在后台工作线程中,而不是说
label4.Text = "Hello";
说
label4.Invoke(new Action(() =>
{
label4.Text = "Hello";
}
));
{}内部的所有内容都在控件的线程上执行,因此您可以避免异常。
这使您可以从BackgroundWorker
对用户界面进行任意更改,而不仅仅是报告进度。
答案 1 :(得分:2)
您可以在BackgroundWorker
中使用ProgressChanged
方法更改标签,并在{{1}}事件处理程序中编写实际代码。
答案 2 :(得分:1)
你应该非常警惕调用同步Invoke而不是gui上的async BeginInvoke。你很快就会有一个反应迟钝的草率,看起来很难自己画画,也有可能造成僵局。
这取决于你更新它的频率 - 你的后台线程真的需要等待gui返回吗?这听起来像你的模型有问题。
答案 3 :(得分:1)
与Control.BeginInvoke一样,您可以查看SynchronizationContext。
当您创建BackgroundWorkers时,假设您是从UI线程创建它们,则将SynchronizationContext.Current传递给worker。当BackgroundWorkers准备好在UI线程上调用某些东西时,它们会在创建它们时传入的SynchronizationContext实例上调用Synchronization.Post方法。
答案 4 :(得分:0)
查看this answer。如果你有一个,五个或一千个工作线程(概念意义上的话)并不重要。