深耕 WPF 开发的各位程序员大大们一定避不开使用 Dispatcher。跨线程访问 UI 当然免不了用到它,将某个任务延迟到当前任务之后执行也会用到它。Dispatcher.Invoke、Dispatcher.BeginInvoke 是过去大家经常使用的方法,而 .Net Framework 4.5 中微软为我们带来了 Dispatcher.InvokeAsync 方法,它和前面两个有何不同?
阅读本文将更深入地了解 Dispatcher 的工作机制。
本文是深入了解 WPF Dispatcher 的工作原理系列文章的一部分:
回顾老旧的 BeginInvoke,看看新的 InvokeAsync
微软自 .Net Framework 3.0 为我们引入了 Dispatcher
之后,BeginInvoke
方法就已存在。不过,看这名字的 Begin
前缀,有没有一种年代感?没错!这是微软在 .Net Framework 1.1 时代就推出的 Begin
/End
异步编程模型(APM,Asynchronous Programming Model)。虽说 Dispatcher.BeginInvoke
并不完全按照 APM 模型来实现(毕竟没有对应的 End
,也没有返回 IAsyncResult
),但这个类型毕竟也是做线程相关的事情,而且这个方法的签名明显还带着那个年代的影子。不止名字上带着 Begin
表示异步的执行,而且参数列表中还存在着 Delegate
和 object
这样古老的类型。要知道,现代化的方法可是 Action
/Func
加泛型啊!
大家应该还对 .Net Framework 4.5 带给我们的重磅更新——async
/await
异步模式感到兴奋,因为它让我们的异步代码变得跟同步代码一样写了。这是微软新推荐的异步编程模式,叫做 TAP(Task-based Asynchronous Pattern)。既然异步编程模式都换了,同为线程服务的 Dispatcher.BeginInvoke
怎能不改呢?于是,微软真的改了,就是从 .Net Framework 4.5 版本开始。
它叫做——Dispatcher.InvokeAsync
。
BeginInvoke 和 InvokeAsync 有什么不同?
这个还真得扒开微软的源码看一看呢!
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public DispatcherOperation BeginInvoke(DispatcherPriority priority, Delegate method);
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public DispatcherOperation BeginInvoke(DispatcherPriority priority, Delegate method, object arg);
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public DispatcherOperation BeginInvoke(DispatcherPriority priority, Delegate method, object arg, params