我知道从另一个线程更新标签的最简单方法是:
void DoSomething()
{
if (InvokeRequired)
{
Invoke(new MethodInvoker(DoSomething));
} else
{
// Do Something
}
}
我的问题是,是否可以更改回主线程并从那里更新GUI,而不是需要从另一个线程更新GUI的if
?
答案 0 :(得分:3)
实际上,最简单的方法是
Invoke(new MethodInvoker(DoSomething));
如果你肯定从另一个线程调用它,即。如果你知道,那InvokeRequired将永远是真的。
此外,您可以使用WinForms Timer来轮询文本字段的更改。此计时器在GUI线程中运行。如果你每秒有数百个事件,这是一个非常好的解决方案。或者至少"很多"。这样你就不会有太多的GUI线程切换(总是花费相当多的时间)。
答案 1 :(得分:0)
当然可能......你可以使用名为Dispatcher的类(System.Windows.Threading)。这个类的主要目的是在线程上发送“请求/调用”...对于gui线程,所有控件都有这样的调度程序实例。您可以将此实例作为窗口的成员找到,例如......
问题是您使用调度程序alraedy(在您发布的代码中)以某种方式...如果您在Form中调用Invoke,则使用此默认/ gui调度程序。并且“IF”用于减少gui线程本身的调用次数。
它的工作方式就像“我在ui线程中吗?不是吗?然后给调度员请求在UI线程上调用相同的方法!...我在UI Thred中吗?是的!好的,我正在做某事。”
如果您100%确定调用此表单而不是UI线程,则可以丢弃该IF并直接调用调度程序。
MyForm.Dispatcher.Invoke( mydelegate, params[] )
或使用一些lambda代替委托或MethodInvoker ...
MyForm.Dispatcher.BeginInvoke( (Action)(()=>{ textbox.text = result; }), null);
根本......你可以存储(在form.load事件中)对UI Dispatcher的引用,以便在不同的类中使用(某些工作类在其他类上做东西)
如果你创建一些更大的UI东西,我建议更好的UI和更容易处理这样的东西是:...考虑一些WPF和MVVM模式和属性更改通知的研究....它会给你非常强大的工具具有“自我更新”和非常可扩展的UI以及数据,工作线程和UI之间的层。