Dispatcher.Invoke()与不创建任何线程

时间:2013-06-05 09:57:58

标签: c# wpf multithreading

在WPF应用程序中,直接调用方法与将其传递给Dispatcher.Invoke()之间有什么区别?根据我到目前为止所读到的内容,两者都在同一个UI线程中执行,不是吗?

示例代码

案例1:

public sealed partial class Window
{ 
    private void SomeEventHandler(object sender, EventArgs e) 
    {
        SomeMethod();
    }
}

案例2:

public sealed partial class Window
{ 
    private void SomeEventHandler(object sender, EventArgs e) 
    {
        Dispatcher.Invoke(SomeMethod, DispatcherPriority.Send);
    }
}

2 个答案:

答案 0 :(得分:6)

如果代码在UI线程上运行,这个问题才有意义。显然,如果从工作线程调用它,则存在巨大的差异。并且您使用Dispatcher.BeginInvoke,而不是Invoke()。让我们的工作“可能是有用的”。

是的,在两种情况下,委托目标都将在UI线程上运行。不同之处在于运行时。当您使用Dispatcher.BeginInvoke()时,它将不会执行,直到您的程序再次空闲并重新进入调度程序循环。通常在当前方法返回后,它取决于它是如何被激活的。

虽然这听起来毫无意义,但在某些情况下可以有用。当由于事件而激活方法并且在事件处理程序中执行某些操作时由于重入问题而非常有用。一个经典的危险就是让事件再次发生,你的代码会用这个网站的名字轰炸。或者,当事件触发后代码运行时,撤消您在事件处理程序中执行的操作。使用Dispatcher.BeginInvoke()是一种延迟执行事件处理程序代码的简洁方法。否则,这将模拟async / await在C#5中的工作方式。

答案 1 :(得分:1)

只要需要在UI线程上运行操作,就可以从后台线程使用UI线程调度程序,例如更新TextBox.Text

而且 Dispatcher maintains a prioritized queue of work items因此您可以使用不同的DispatcherPriority投放操作 例如,您希望以Background优先级执行操作意味着在完成所有其他非空闲操作后处理操作的含义。