Control.Dispatcher.BeginInvoke()和Control.Dispatcher.Invoke()命令执行令人困惑?

时间:2013-08-03 10:54:44

标签: c# wpf

我正在使用WPF,我对执行顺序Control.Dispatcher.BeginInvoke()Control.Dispatcher.Invoke()感到困惑。

我将在

下面显示代码示例
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");
    }));
}

我希望“命令1”将在“命令2”之前运行并完成,但有时似乎“命令2”在“命令1”之前运行。我对互联网和MSDN文档进行了很多研究,但我不明白为什么会这样。

有人请告诉我这些功能的规则吗?

非常感谢!

T& T公司

4 个答案:

答案 0 :(得分:6)

BeginInvoke调用Action在与Dispatcher相关联的线程上异步传递给Invoke,同时Invoke同步调用该行为。

换句话说,Action会立即执行您传递给BeginInvoke的内容,而Dispatcher会将您传递给它的操作放在Dispatcher队列上,就像一个Dispatcher将要做的事情的列表,但不能保证何时发生,或者一旦调度员完成其他事情等待该队列。

因此有时候BeginInvoke可能忙着做其他事情并将你传递给Invoke的动作放在队列的末尾,直到它可以执行它,然后它执行你传递给{{{0}的任何动作。 1}}立即,这就是订单差异的原因。

答案 1 :(得分:1)

  

有人请告诉我这些功能的规则

以下是差异

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

现在你的理解

  

我希望“命令1”在“命令2”之前运行并完成,   但有时似乎“命令2”在“命令1”之前运行

由于您的第一个电话是异步的,因此它可能在您第二次通话之前或之后完成(这是同步的)。

答案 2 :(得分:1)

  

我希望“命令1”在“命令2”之前运行并完成,   但有时似乎“命令2”在“命令1”之前运行。

您的假设是错误的,因为Control.BeginInvokeControl.Invoke同步运行时异步运行。

如果要确保在命令2之前运行命令1,请使用Invoke运行命令1。

当你使用BeginInvoke时,你没有得到order guarantee,因为在它执行它时它取决于Dispatcher。

答案 3 :(得分:1)

嗯,我认为嗅探器的答案非常清楚。基本上你在这里得到了几乎所有的想法,最后可能需要你组织这些概念。

1,你调用的调用会将当前的主线程执行切换到UI线程同步,当然,如果它是一个loooong运行,会阻塞主线程,直到你的调用代码完成; 2, BeginInvoke 的区别在于此切换发生异步,不会影响主线程。

我假设您已经理解了为什么输出序列