0

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

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

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

4

2 回答 2

3

实际上,最简单的方法是

Invoke(new MethodInvoker(DoSomething));

如果你确定从另一个线程调用它,即。如果您知道,那 InvokeRequired 将始终为真。

此外,您可以使用 WinForms 计时器来轮询文本字段的更改。此计时器在 GUI 线程中运行。如果每秒有数百个事件,这是一个很好的解决方案。或者至少“很多”。这样,您就不需要太多切换到 GUI 线程(这总是需要相当长的时间)。

于 2013-05-21T11:23:55.350 回答
0

当然有可能……您可以使用名为 Dispatcher (System.Windows.Threading) 的类。此类的主要目的是在线程上分派“请求/调用”……对于 gui 线程,所有控件都可以使用此类分派器的实例。例如,您可以将此实例作为 Window 的成员...

问题是您已经以某种方式使用调度程序(在您发布的代码中)......如果您在 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 之间的层。

于 2013-05-21T11:26:52.940 回答