访问由另一个线程创建的对象,而不是每次调用?

时间:2016-09-08 18:47:26

标签: c# multithreading winforms controls invoke

我有一个简单的状态标签,我在长时间运行的例程中经常更新。例程在一个计时器上,因此在另一个线程上,所以我得到Cross-thread operation not valid错误。我在SO上找到了修复,看起来像这样:

lblQuery1Status.Invoke(new Action(delegate
{
    lblQuery1Status.Text = "Status: Publishing";
}));

但是,我在例行程序中更新了此控件的文本7或8次。有更有效或简单的方法吗?

3 个答案:

答案 0 :(得分:3)

如果你想"简化"语法,你总是可以使用内联lambda来缩短"缩短"语法:

lblQuery1Status.Invoke(new Action(() => lblQuery1Status.Text = "Status: Publishing"));

您还可以为调用创建操作变量,并在需要时重新调用操作:

Action updateStatus = () => 
    lblQuery1Status.Invoke(new Action(() => lblQuery1Status.Text = "Status: Publishing"));

然后,您可以根据需要多次将其作为方法调用:

updateStatus();

答案 1 :(得分:1)

这是我使用的解决方案,基于@David L' answer above

动作定义:

Action<string> updateStatus = (s) => 
     statusLabel[qo.id].Invoke(new Action(() => statusLabel[qo.id].Text = s));

呼叫:

updateStatus("Opening Connection");

我意识到它没有效率,但它更简单,更清洁,而且让我更少畏缩。

答案 2 :(得分:0)

不幸的是,这是从长时间运行的任务/线程到UI线程获取数据的最佳方式,编组有其开销,但除非你每秒呼叫数百次,否则我认为你&#39 ;好吧