从c#中的另一个线程更新GUI -是否更改回主线程
本文关键字:线程 是否 更新 另一个 GUI | 更新日期: 2023-09-27 18:14:29
我知道从另一个线程更新标签的最简单方法是:
void DoSomething()
{
if (InvokeRequired)
{
Invoke(new MethodInvoker(DoSomething));
} else
{
// Do Something
}
}
我的问题是,如果不是需要从另一个线程更新GUI的if
,是否有可能更改回主线程并从那里更新GUI ?
实际上,最简单的方法是
Invoke(new MethodInvoker(DoSomething));
,如果你从另一个线程调用它,即。如果你知道,那么invokerrequired_true将永远为真。
同样,你可以使用WinForms Timer来轮询文本字段的变化。这个计时器在GUI线程中运行。这是一个很好的解决方案,如果你每秒有几百个事件。或者至少"很多"。这样,您就不会有太多的GUI线程切换(这总是要花费相当多的时间)。
当然有可能…你可以使用Dispatcher (System.Windows.Threading)类。这个类的主要目的是在线程上调度"请求/调用"。对于GUI线程,有一个可用于所有控件的调度程序实例。你可以找到这个实例作为你的窗口的成员,例如…
问题是你已经在某种程度上使用了dispatcher(在你发布的代码中)…如果在Form内部调用Invoke,则使用默认的/gui调度程序。"IF"是为了减少gui线程本身的调用次数。
它的工作原理就像"我在ui线程吗?"没有?然后给调度程序请求在UI线程上调用相同的方法!…我在UI线程中吗?是的!好吧,我在做点什么。"
如果你100%确定你调用这个表单而不是UI线程,你可以扔掉If直接调用dispatcher
MyForm.Dispatcher.Invoke( mydelegate, params[] )
或者使用lambda代替delegate或MethodInvoker…
MyForm.Dispatcher.BeginInvoke( (Action)(()=>{ textbox.text = result; }), null);
而且……你可以在表单中存储。引用UI Dispatcher在不同的类中使用(一些工作类在其他类上做事情)
如果你要创建一些更大的UI,我的建议是更好的UI和更容易处理这样的东西:…考虑一些WPF和MVVM模式和属性更改通知的研究....它将给你一个非常强大的工具,具有"自我更新"和非常可伸缩的UI,以及数据,工作线程和UI之间的层。