0

I'm working on a WPF application.

On the server, there are many-many threads / tasks that throw actions that the UI is registered to.

The listeners are invoked on the same thread in which the actions were raised, so in the listeners in the UI, when I want to update UI elements I need to connect to the UI thread via Application.Current.Dispatcher.BeginInvoke(action) or Application.Current.Dispatcher.Invoke(action).

When lots of threads raise those actions, there are lots of calls to the Application.Current.Dispatcher.Invoke(action) (I use Invoke for now), sometimes in the range of a few milliseconds.

After a while, if I put a breakpoint before Application.Current.Dispatcher.Invoke and a breakpoint inside the action itself, there might be several seconds, even more than 5, for connecting to the UI thread Dispatcher, and for the actual action to actually start executing.

On the other hand, why would Application.Current.Dispatcher.BeginInvoke(action) solve my problem?

I mean, we have only one UI thread, so the BeginInvoke method will just put those many operations in a queue, and it will still take a lot of time for action X to happen. I don't think this will make any action that is supposed to run on the UI thread, start faster (when the UI thread is busy). Am I right?

My purpose is:

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

                   OnPropertyChanged(() => SliderText);
                });}

I want the action to start executing the rows

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

                   OnPropertyChanged(() => SliderText);

as soon as possible when I get to the method UpdateScreen()

Why would BeginInvoke be better than Invoke, if it's actually even better?

DimaK
  • 721
  • 1
  • 6
  • 26
  • Dispatcher.Invoke() was a serious design mistake. It is only *required* when you need the return value, if you do then you're hiding a threading race bug. Sadly it wasn't until UWP that Microsoft recognized the mistake, CoreDispatcher only has a RunAsync() method. – Hans Passant Feb 13 '19 at 14:59

1 Answers1

1

For your purpose, there is no difference between Invoke and BeginInvoke. Dispatcher is a task scheduler associated with one specific thread. You can add tasks via Invoke or BeginInvoke to a prioritized queue of the Dispatcher, the Dispatcher will execute them one by one on the thread it associated with. But Invoke will block caller thread until task was completed, so using it may has negative effect on your working thread.

Alex.Wei
  • 1,300
  • 4
  • 10