从C#中的另一个线程更新GUI – 是否更改回主线程?
我知道从另一个线程更新标签的最简单方法是:
void DoSomething() { if (InvokeRequired) { Invoke(new MethodInvoker(DoSomething)); } else { // Do Something } }
我的问题是, if
不需要从另一个线程更新GUI,是否可以更改回主线程并从那里更新GUI?
实际上,最简单的方法是
Invoke(new MethodInvoker(DoSomething));
如果你肯定从另一个线程调用它,即。 如果你知道,那InvokeRequired将永远是真的。
此外,您可以使用WinForms Timer来轮询文本字段的更改。 此计时器在GUI线程中运行。 如果你每秒有数百个事件,这是一个非常好的解决方案。 或者至少“很多”。 这样,您没有太多的GUI线程切换(这总是需要相当长的时间)。
当然可能……你可以使用名为Dispatcher的类(System.Windows.Threading)。 这个类的主要目的是在线程上发送“请求/调用”…对于gui线程,有一个这样的调度程序的实例可用于所有控件。 你可以找到这个实例作为你的Window的成员,例如……
问题是您使用调度程序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之间的层。