从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之间的层。