访问由另一个线程创建的对象而不每次都调用?
Posted
技术标签:
【中文标题】访问由另一个线程创建的对象而不每次都调用?【英文标题】:Access object created by another thread without invoking every time? 【发布时间】:2017-01-16 19:31:25 【问题描述】:我有一个简单的状态标签,我在长时间运行的例程中经常更新它。该例程在计时器上,因此在另一个线程上,所以我收到Cross-thread operation not valid
错误。我在 SO 上找到了一个修复程序,如下所示:
lblQuery1Status.Invoke(new Action(delegate
lblQuery1Status.Text = "Status: Publishing";
));
但是,我在例行程序中更新了此控件的文本 7 或 8 次。有没有更有效或更简单的方法来做到这一点?
【问题讨论】:
它有什么低效之处?如果您需要执行 7-8 次,请将其粘贴在一个名为 status 作为字符串输入的方法中。我在看你的代表,我真的不想刻薄——只是好奇你说高效时你在交流什么? 我想我想知道是否可以在新线程中调用它一次,而不是每次需要访问它时调用它。我是.net
的新手,尤其是线程。
【参考方案1】:
如果你想“简化”语法,你总是可以使用内联 lambda 来“缩短”语法:
lblQuery1Status.Invoke(new Action(() => lblQuery1Status.Text = "Status: Publishing"));
您还可以为调用创建一个动作变量,并在需要时重新调用该动作:
Action updateStatus = () =>
lblQuery1Status.Invoke(new Action(() => lblQuery1Status.Text = "Status: Publishing"));
然后您可以根据需要多次调用它:
updateStatus();
【讨论】:
是的,我知道invoke
没有创建新线程,我只是希望有一种方法可以在 on 新线程后调用它并多次引用它之后(无需每次都调用)
@Scott 啊,我的错。上次更新是否更接近您正在寻找的内容?
毫无疑问,Action 句柄看起来很有趣。我会研究一下。谢谢。【参考方案2】:
这是我采用的解决方案,基于@David L 的answer above。
动作定义:
Action<string> updateStatus = (s) =>
statusLabel[qo.id].Invoke(new Action(() => statusLabel[qo.id].Text = s));
呼叫:
updateStatus("Opening Connection");
我意识到它并没有更高效,但它更简单、更干净,让我不再畏缩。
【讨论】:
【参考方案3】:不幸的是,这是将数据从长时间运行的任务/线程获取到 UI 线程的最佳方式,编组有其开销,但除非你每秒调用数百次,否则我认为你会没事的 ?
【讨论】:
以上是关于访问由另一个线程创建的对象而不每次都调用?的主要内容,如果未能解决你的问题,请参考以下文章
Servlet第二篇Servlet实现线程安全及其他细节补充
Wpf中“由于其他线程拥有此对象,因此调用线程无法对其进行访问”