从c#中的另一个线程更新GUI -是否更改回主线程

本文关键字:线程 是否 更新 另一个 GUI | 更新日期: 2023-09-27 18:14:29

我知道从另一个线程更新标签的最简单方法是:

void DoSomething()
{
    if (InvokeRequired)
    {
        Invoke(new MethodInvoker(DoSomething));
    } else 
    {
        // Do Something
    }
}

我的问题是,如果不是需要从另一个线程更新GUI的if,是否有可能更改回主线程并从那里更新GUI ?

从c#中的另一个线程更新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之间的层。