0

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

示例代码

情况1:

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

案例二:

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

2 回答 2

6

这个问题只有在代码在 UI 线程上运行时才有意义。显然,如果您从工作线程中调用它,则会有很大的不同。你使用 Dispatcher.BeginInvoke,而不是 Invoke()。所以让我们从“可能有用”的角度出发。

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

虽然这听起来毫无意义,但在某些情况下它可能很有用。当方法由于事件而被激活并且由于重入问题而在事件处理程序中执行某些操作很危险时很有用。一个典型的危险是让事件再次触发,您的代码将与该网站的名称一起爆炸。或者当代码在事件触发后运行时,会撤消您在事件处理程序中所做的事情。使用 Dispatcher.BeginInvoke() 是一种延迟事件处理程序代码执行的干净方法。否则,这模拟了 C# 5 中 async/await 的工作方式。

于 2013-06-05T10:13:44.213 回答
1

每当您需要在 UI 线程上运行操作时,您可以使用后台线程中的 UI 线程调度程序,例如更新 TextBox.Text

此外 ,您可以使用不同的DispatcherPriorityDispatcher maintains a prioritized queue of work items运行操作, 例如您希望您的操作 优先执行 这意味着在所有其他非空闲操作完成后处理操作。Background

于 2013-06-05T10:07:32.400 回答