views:

338

answers:

4

I need to know whether Control.BeginInvoke and Control.Invoke calls will execute in the order they are called.

I have the following scenario:

  1. UI thread is blocked
  2. WCF thread calls Control.BeginInvoke
  3. WCF thread calls Control.Invoke (or possibly BeginInvoke again)
  4. UI thread is unblocked
  5. ??

The execution order of step 1-4 is guaranteed to be in the shown order (technically the order is not guaranteed to be that way, but the question I have is only relevant if the order is as shown).

The question I have is whether there is any chance that the Invoke/BeginInvoke call in step 3 is executed before the BeginInvoke call in step 2?

Also, please don't comment on blocking the UI thread.

A: 

Not enough information to give you a good answer. The UI thread is blocked so steps 2 and 3 must be running on a different thread. If there's no synchronization between the two, then how could we know any ordering?

Thread 1        Thread 2                       Thread 3         Thread 4
Block UI        Calls BeginInvoke              
Unblock UI      Calls Invoke or BeginInvoke    BeginInvoke runs  BeginInvoke runs

You've got a lot a parallelism going on, but from what you've described, there's no possible way we could tell you what possible orderings will occur, short of saying, "Anything." We can't even tell you that the calls to BeginInvoke won't happen before the UI thread is blocked or after the UI thread is unblocked.

Greg D
Well, the order of steps 1-4 is guaranteed to happen in that order. The question is only whether this will also guarantee the execution order of the BeginInvoke/Invoke calls in steps 3 and 4. I'm updating the question to make this more clear.
cornergraf
Ahhh, the edit that states it's `Control.BeginInvoke` and `Control.Invoke` changes a lot. Glad somebody was able to cover it for you. :)
Greg D
Yeah, and I just realized again how much one tends to take certain information for granted when discussing with others. I will try to be more precise in the future. Thanks for your response though.
cornergraf
A: 

BeginInvoke calls are queued on the destination thread (as they are posted in order of arrival).

Synchronous calls on the WCF Thread (step 3) may be executed before asynchronous calls (step 2) made from this thread.

Laurent Etiemble
Ok, thanks a lot. Would you happen to have a source for that statement? I have tried to find something definite on google, but without success so far.
cornergraf
+1  A: 

In your case, step 2 will always execute before step 3. BeginInvoke on the UI thread will execute in the order it has been queued.

The UI thread is in fact a message pump, it has a single message queue with only one thread consuming it, so it's guaranteed that work items will be executed in the order they were queued.

It's with Delegate.BeginInvoke that the order of execution may be non-sequential.

SelflessCoder
So the comment stating that synchronous Invoke calls may be executed before the asynchronous BeginInvoke call does not apply for Control.BeginInvoke, but it would apply for Delegate.BeginInvoke?Can you provide me with a link that explains this?
cornergraf
Your statement is correct. I added an short explanation of the UI message pump in the answer, weirdly I can't find an official source stating it.
SelflessCoder
Ok, thanks. I do know about the MessagePump in general, but I thought that BeginInvoke/Invoke calls could potentially have special behavior for whatever reason and I wanted to be sure
cornergraf
In step 1, the UI is said blocked. So if the WCF thread invoke a call on the UI thread (via BeginInvoke), it cannot be executed before the UI thread is unblocked. Am I wrong ?
Laurent Etiemble
You are correct. The question is about what happens after the UI thread is unblocked again, which of the two BeginInvoke/Invok calls gets executed first.
cornergraf
I just tested this and found this answer to be wrong (.NET 3.5, if that matters). Invoke calls can be executed before prior BeginInvoke calls.
mafutrct
A: 

No chance you can assume that but if there's actual some form of dependency between the two calls above have them waiting on a semaphore and only execute the dependent code when they're both completed.

If the reason why you're making the two calls at the same time is not performance then I would probably just execute the second call in the callback of the first (makes it a lot easier to debug).

ruibm
actually, step 3 and 4 might be swapped, but if they are I know that (obviously) step 2 will execute first. Therefore my question is only relevant in the case that the order of execution is exactly as presented, which is why I phrased it that way
cornergraf