多个Control.BeginInvoke / Invoke调用会按顺序执行吗?

时间:2022-09-22 04:25:57

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

我需要知道Control.BeginInvoke和Control.Invoke调用是否将按照调用的顺序执行。

I have the following scenario:

我有以下情况:

  1. UI thread is blocked
  2. UI线程被阻止

  3. WCF thread calls Control.BeginInvoke
  4. WCF线程调用Control.BeginInvoke

  5. WCF thread calls Control.Invoke (or possibly BeginInvoke again)
  6. WCF线程调用Control.Invoke(或者可能再次使用BeginInvoke)

  7. UI thread is unblocked
  8. UI线程已解除阻止

  9. ??

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).

步骤1-4的执行顺序保证按所示顺序排列(从技术上讲,顺序不保证是这样的,但是我所拥有的问题仅在订单如图所示时才相关)。

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?

我的问题是,在步骤2中的BeginInvoke调用之前是否有可能执行步骤3中的Invoke / BeginInvoke调用?

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

另外,请不要评论阻​​止UI线程。

4 个解决方案

#1


10  

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.

在您的情况下,步骤2将始终在步骤3之前执行.UI线程上的BeginInvoke将按其排队的顺序执行。

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.

UI线程实际上是一个消息泵,它有一个消息队列,只有一个线程消耗它,所以它保证工作项将按它们排队的顺序执行。

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

使用Delegate.BeginInvoke,执行顺序可能是非顺序的。

#2


3  

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

BeginInvoke调用在目标线程上排队(因为它们按到达顺序发布)。

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

可以在从该线程进行异步调用(步骤2)之前执行WCF线程上的同步调用(步骤3)。

#3


0  

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?

没有足够的信息给你一个很好的答案。 UI线程被阻止,因此步骤2和3必须在不同的线程上运行。如果两者之间没有同步,那么我们怎么知道任何排序?

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.

你已经有了很多并行性,但是根据你所描述的,我们没有办法告诉你可能会出现什么样的排序,而不是说“任何东西”。我们甚至不能告诉您,在UI线程被阻止之前或在UI线程被解除阻塞之后,不会发生对BeginInvoke的调用。

#4


0  

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).

如果您同时进行两次调用的原因不是性能,那么我可能只是在第一次调用中执行第二次调用(使调试更加容易)。

#1


10  

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.

在您的情况下,步骤2将始终在步骤3之前执行.UI线程上的BeginInvoke将按其排队的顺序执行。

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.

UI线程实际上是一个消息泵,它有一个消息队列,只有一个线程消耗它,所以它保证工作项将按它们排队的顺序执行。

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

使用Delegate.BeginInvoke,执行顺序可能是非顺序的。

#2


3  

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

BeginInvoke调用在目标线程上排队(因为它们按到达顺序发布)。

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

可以在从该线程进行异步调用(步骤2)之前执行WCF线程上的同步调用(步骤3)。

#3


0  

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?

没有足够的信息给你一个很好的答案。 UI线程被阻止,因此步骤2和3必须在不同的线程上运行。如果两者之间没有同步,那么我们怎么知道任何排序?

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.

你已经有了很多并行性,但是根据你所描述的,我们没有办法告诉你可能会出现什么样的排序,而不是说“任何东西”。我们甚至不能告诉您,在UI线程被阻止之前或在UI线程被解除阻塞之后,不会发生对BeginInvoke的调用。

#4


0  

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).

如果您同时进行两次调用的原因不是性能,那么我可能只是在第一次调用中执行第二次调用(使调试更加容易)。