Reputation: 3713
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
Upvotes: 6
Views: 2126
Reputation: 98
well, i think sniffer's answer is pretty clear enough. basiclly you get almost all the idea here, the last thing may need your orgnize those concepts.
1, the Invoke here you called will switch the current main thread execution to the UI thread synchronously, of course, if it's a loooong running, will block the main thread until your invoke code completion; 2, The difference of BeginInvoke is that this switch happens asynchronously, wouldn't affect the main thread.
and i assume you already understand why the output sequence
Upvotes: 2
Reputation: 32721
Someone please tell me the rule of these functions exactly
Following is the diffrence
Dispatcher.Invoke: Executes the specified delegate synchronously on the thread the Dispatcher is associated with
Dispatcher.BeginInvoke: Executes the specified delegate asynchronously on the thread the Dispatcher is associated with..
and now your understanding
I expect the "Command 1" will be run and finished before "command 2", but sometimes It seems the "Command 2" run before "Command 1"
As your first call is Asynchronous so it may finish before or after your second call (which is synchronous).
Upvotes: 2
Reputation: 30117
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.
Upvotes: 1
Reputation: 19423
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.
Upvotes: 7