6

我正在使用 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 文档上进行了很多研究,但我不明白为什么会发生这种情况。

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

非常感谢!

电通

4

4 回答 4

6

BeginInvoke在与while同步调用该操作Action关联的线程上异步调用您传递给它的线程。DispatcherInvoke

换句话说,Invoke立即执行您传递给它的任何Action内容,同时BeginInvoke将您传递给它的操作放在Dispatcher队列中,这就像将Dispatcher要做的事情的列表,但不能保证何时或尽快发生调度程序已完成等待该队列的其他事情。

因此,有时Dispatcher可能会忙于做其他事情并将您传递给队列的操作BeginInvoke放在队列的末尾,直到它可以执行它,然后它Invoke立即执行您传递给的任何操作,这就是顺序差异的原因。

于 2013-08-03T11:07:26.913 回答
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”之前运行

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

于 2013-08-03T11:10:42.617 回答
1

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

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

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

当您使用时,BeginInvoke您不会得到,order guarantee因为它取决于 Dispatcher 何时执行它。

于 2013-08-03T11:11:04.653 回答
1

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

1、你这里调用的Invoke会同步切换当前主线程执行到UI线程,当然如果是长时间运行,会阻塞主线程直到你的invoke代码完成;2、BeginInvoke的不同之处在于这个切换是异步发生的,不会影响主线程。

我假设你已经明白为什么输出序列

于 2013-08-03T12:14:51.713 回答