Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Control.Dispatcher.BeginInvoke() and Control.Dispatcher.Invoke() order execution is confusing?

Tags:

c#

wpf

I'm using WPF, and I was confused about the order of execution Control.Dispatcher.BeginInvoke() and Control.Dispatcher.Invoke().

I will show an example of code below

backgroundThread = new Thread(BackgroundThread);
backgroundThread.Start();
public void BackgroundThread()
{
    this.Dispatcher.BeginInvoke(new Action(delegate()
    {
      WriteLog("Run command 1");
    }));

    this.Dispatcher.Invoke(new Action(delegate()
    {
      WriteLog("Run command 2");
    }));
}

I expect the "Command 1" will be run and finished before "command 2", but sometimes It seems the "Command 2" run before "Command 1". I have researched much on internet and MSDN document, but I don't understand why this happen.

Someone please tell me the rule of these functions exactly?

Many thanks!

T&T

like image 746
TTGroup Avatar asked Aug 03 '13 10:08

TTGroup


2 Answers

BeginInvoke calls the Action you pass to it asynchronously on the thread that is associated with the Dispatcher while Invoke calls that action synchronously.

In other words, Invoke immediately executes what ever Action you pass to it while BeginInvoke puts the action you pass to it on the Dispatcher queue which is like a list of the things the Dispatcher is going to do but with no guarantee when that is going to happen or as soon as the dispatcher has finished doing the other things waiting on that queue.

So sometimes the Dispatcher might be busy doing something else and puts the action you pass to BeginInvoke on the queue's end until it can execute it, and then it executes whatever action you pass to Invoke immediately and that is the reason for the order differences.

like image 170
Ibrahim Najjar Avatar answered Oct 29 '22 04:10

Ibrahim Najjar


I expect the "Command 1" will be run and finished before "command 2", but sometimes It seems the "Command 2" run before "Command 1".

Your assumption is wrong because Control.BeginInvoke runs asynchronously while the Control.Invoke runs synchronously.

If you want to make sure command 1 runs before command 2, run command 1 using Invoke.

When you use BeginInvoke you are not getting the order guarantee because it's upto Dispatcher when it's going to execute it.

like image 31
Haris Hasan Avatar answered Oct 29 '22 04:10

Haris Hasan