我正在使用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公司
答案 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.BeginInvoke
在Control.Invoke
同步运行时异步运行。
如果要确保在命令2之前运行命令1,请使用Invoke
运行命令1。
当你使用BeginInvoke
时,你没有得到order guarantee
,因为在它执行它时它取决于Dispatcher。
答案 3 :(得分:1)
1,你调用的调用会将当前的主线程执行切换到UI线程同步,当然,如果它是一个loooong运行,会阻塞主线程,直到你的调用代码完成; 2, BeginInvoke 的区别在于此切换发生异步,不会影响主线程。
我假设您已经理解了为什么输出序列