15

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

我有以下情况:

  1. UI线程被阻塞
  2. WCF 线程调用 Control.BeginInvoke
  3. WCF 线程调用 Control.Invoke(或可能再次调用 BeginInvoke)
  4. UI线程未阻塞
  5. ??

步骤 1-4 的执行顺序保证按照显示的顺序(从技术上讲,不能保证顺序是那样的,但我的问题只有在顺序如图所示的情况下才相关)。

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

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

4

4 回答 4

12

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

UI 线程实际上是一个消息泵,它有一个消息队列,只有一个线程在使用它,因此可以保证工作项将按照它们排队的顺序执行。

对于 Delegate.BeginInvoke,执行顺序可能是非顺序的。

于 2009-12-10T13:31:18.730 回答
3

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

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

于 2009-12-10T13:24:41.023 回答
0

没有足够的信息给你一个好的答案。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

您有很多并行性,但是根据您的描述,我们无法告诉您可能会发生什么排序,除非说“任何事情”。我们甚至无法告诉您在 UI 线程被阻塞之前或 UI 线程被解除阻塞之后不会发生对 BeginInvoke 的调用。

于 2009-12-10T13:14:40.730 回答
0

您不可能假设,但如果上述两个调用之间存在某种形式的依赖关系,则让它们等待信号量,并且仅在它们都完成时才执行依赖代码。

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

于 2009-12-10T13:39:22.653 回答