【问题标题】:Will multiple Control.BeginInvoke/Invoke calls execute in order?多个 Control.BeginInvoke/Invoke 调用会按顺序执行吗?
【发布时间】:2009-12-10 13:07:25
【问题描述】:

我需要知道 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 线程。

【问题讨论】:

    标签: c# .net invoke begininvoke


    【解决方案1】:

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

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

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

    【讨论】:

    • 那么说明同步Invoke调用可能在异步BeginInvoke调用之前执行的注释不适用于Control.BeginInvoke,但它会适用于Delegate.BeginInvoke?你能给我一个解释这个的链接吗?
    • 你的说法是正确的。我在答案中添加了对 UI 消息泵的简短解释,奇怪的是我找不到说明它的官方来源。
    • 好的,谢谢。我确实了解 MessagePump,但我认为 BeginInvoke/Invoke 调用可能出于任何原因而具有特殊行为,我想确定
    • 在第 1 步中,UI 被说成被阻塞了。因此,如果 WCF 线程调用 UI 线程上的调用(通过 BeginInvoke),则在解锁 UI 线程之前无法执行它。我错了吗?
    • 你是对的。问题是 UI 线程再次解锁后会发生什么,两个 BeginInvoke/Invok 调用中的哪一个首先执行。
    【解决方案2】:

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

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

    【讨论】:

    • 好的,非常感谢。你会碰巧有那个声明的来源吗?我试图在谷歌上找到一些确定的东西,但到目前为止没有成功。
    【解决方案3】:

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

    【讨论】:

    • 嗯,步骤 1-4 的顺序保证按照该顺序发生。问题只是这是否也能保证第 3 步和第 4 步中 BeginInvoke/Invoke 调用的执行顺序。我正在更新问题以使这一点更清楚。
    • 啊,声明它是Control.BeginInvokeControl.Invoke 的编辑变化很大。很高兴有人能够为你掩盖它。 :)
    • 是的,我又一次意识到,在与他人讨论时,人们倾向于将某些信息视为理所当然。以后我会尽量做到更精确。不过感谢您的回复。
    【解决方案4】:

    你不能假设,但是如果上面的两个调用之间存在某种形式的依赖关系,那么让它们等待一个信号量,并且只有在它们都完成时才执行依赖的代码。

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

    【讨论】:

    • 实际上,第 3 步和第 4 步可能会互换,但如果是,我知道(显然)第 2 步将首先执行。因此,我的问题仅在执行顺序与呈现的完全一致的情况下才相关,这就是我这样表述的原因
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-18
    • 2019-07-07
    • 2011-03-02
    • 2019-12-31
    • 1970-01-01
    • 2019-10-28
    相关资源
    最近更新 更多