Application.Current.Dispatcher.BeginInvoke(action) VS。 Application.Current.Dispatcher.Invoke(action)

Posted

技术标签:

【中文标题】Application.Current.Dispatcher.BeginInvoke(action) VS。 Application.Current.Dispatcher.Invoke(action) (WPF) [重复]【英文标题】:Application.Current.Dispatcher.BeginInvoke(action) VS. Application.Current.Dispatcher.Invoke(action) (WPF) [duplicate] 【发布时间】:2019-07-07 06:19:43 【问题描述】:

我正在开发一个 WPF 应用程序。

在服务器上,有许多线程/任务会抛出 UI 注册到的操作。

侦听器在引发操作的同一线程上调用,因此在 UI 的侦听器中,当我想更新 UI 元素时,我需要通过 Application.Current.Dispatcher.BeginInvoke(行动) 或 Application.Current.Dispatcher.Invoke(action)。

当大量线程引发这些操作时,会多次调用 Application.Current.Dispatcher.Invoke(action)(我现在使用 Invoke),有时在几毫秒的范围内。

过了一会儿,如果我在之前放了一个断点 Application.Current.Dispatcher.Invoke 以及动作本身内部的断点,连接到 UI 线程 Dispatcher 以及实际开始执行的实际动作可能需要几秒钟,甚至超过 5 秒。

另一方面,为什么 Application.Current.Dispatcher.BeginInvoke(action) 会解决我的问题?

我的意思是,我们只有一个 UI 线程,所以 BeginInvoke 方法只会将这些操作放在一个队列中,而动作 X 仍然需要很长时间才能发生。我认为这不会使任何应该在 UI 线程上运行的操作启动得更快(当 UI 线程忙时)。我说的对吗?

我的目的是:

private void UpdateScreen()
               Application.Current.Dispatcher.Invoke(() =>
                
                    OnPropertyChanged(() => Time);
                    OnPropertyChanged(() => TimeFormatted);

                   OnPropertyChanged(() => SliderText);
                );

我希望动作开始执行行

OnPropertyChanged(() => Time);
                    OnPropertyChanged(() => TimeFormatted);

                   OnPropertyChanged(() => SliderText);

当我到达方法 UpdateScreen() 时尽快

如果 BeginInvoke 实际上更好,为什么会比 Invoke 更好?

【问题讨论】:

Dispatcher.Invoke() 是一个严重的设计错误。只有当您需要返回值时才需要,如果您这样做了,那么您就隐藏了线程竞争错误。遗憾的是直到 UWP 微软才意识到这个错误,CoreDispatcher 只有一个 RunAsync() 方法。 【参考方案1】:

出于您的目的,InvokeBeginInvoke 之间没有区别。 Dispatcher 是与一个特定线程相关联的任务调度程序。您可以通过InvokeBeginInvoke 将任务添加到Dispatcher 的优先队列中,Dispatcher 将在与其关联的线程上一一执行。但是Invoke 会阻塞调用者线程直到任务完成,所以使用它可能会对你的工作线程产生负面影响。

【讨论】:

以上是关于Application.Current.Dispatcher.BeginInvoke(action) VS。 Application.Current.Dispatcher.Invoke(action)的主要内容,如果未能解决你的问题,请参考以下文章