InvokeAsync和WPF Dispatcher的BeginInvoke之间有什么区别
我注意到在.NET 4.5中, WPF Dispatcher已经获得了一组新的方法来在Dispatcher的线程上执行一些名为InvokeAsync的东西 。 在.NET 4.5之前,我们有Invoke和BeginInvoke分别同步和asynchronous地处理这个事件。
除了命名和稍微不同的重载之外, BeginInvoke
和InvokeAsync
方法之间还有什么重大区别吗?
哦,我已经检查过了,都可以await
:
private async Task RunStuffOnUiThread(Action action) { // both of these works fine await dispatcher.BeginInvoke(action); await dispatcher.InvokeAsync(action); }
BeginInvoke
方法调用私有的LegacyBeginInvokeImpl
方法没有任何区别,它可以调用私有方法InvokeAsyncImpl
( InvokeAsync
使用的方法)。 所以基本上是一样的 这似乎是一个简单的重构,然而奇怪的是BeginInvoke
方法没有被标记为废弃。
BeginInvoke:
public DispatcherOperation BeginInvoke(DispatcherPriority priority, Delegate method) { return this.LegacyBeginInvokeImpl(priority, method, null, 0); } private DispatcherOperation LegacyBeginInvokeImpl(DispatcherPriority priority, Delegate method, object args, int numArgs) { Dispatcher.ValidatePriority(priority, "priority"); if (method == null) { throw new ArgumentNullException("method"); } DispatcherOperation dispatcherOperation = new DispatcherOperation(this, method, priority, args, numArgs); this.InvokeAsyncImpl(dispatcherOperation, CancellationToken.None); return dispatcherOperation; }
InvokeAsync:
public DispatcherOperation InvokeAsync(Action callback, DispatcherPriority priority) { return this.InvokeAsync(callback, priority, CancellationToken.None); } public DispatcherOperation InvokeAsync(Action callback, DispatcherPriority priority, CancellationToken cancellationToken) { if (callback == null) { throw new ArgumentNullException("callback"); } Dispatcher.ValidatePriority(priority, "priority"); DispatcherOperation dispatcherOperation = new DispatcherOperation(this, priority, callback); this.InvokeAsyncImpl(dispatcherOperation, cancellationToken); return dispatcherOperation; }
方法签名有所不同:
BeginInvoke(Delegate, Object[]) InvokeAsync(Action)
对于BeginInvoke()
编译器隐式地创build数组Object[]
而InvokeAsync()
这样的数组是不需要的:
IL_0001: ldarg.0 IL_0002: call instance class [WindowsBase]System.Windows.Threading.Dispatcher [WindowsBase]System.Windows.Threading.DispatcherObject::get_Dispatcher() IL_0007: ldarg.1 IL_0008: ldc.i4.0 IL_0009: newarr [mscorlib]System.Object IL_000e: callvirt instance class [WindowsBase]System.Windows.Threading.DispatcherOperation [WindowsBase]System.Windows.Threading.Dispatcher::BeginInvoke(class [mscorlib]System.Delegate, object[]) IL_0014: ldarg.0 IL_0015: call instance class [WindowsBase]System.Windows.Threading.Dispatcher [WindowsBase]System.Windows.Threading.DispatcherObject::get_Dispatcher() IL_001a: ldarg.1 IL_001b: callvirt instance class [WindowsBase]System.Windows.Threading.DispatcherOperation [WindowsBase]System.Windows.Threading.Dispatcher::InvokeAsync(class [mscorlib]System.Action)
[编辑 – 都是一样的]
Thereotically
BeginInvoke在创build调度程序的线程上工作,InvokeAsync在调度程序关联的线程上工作。
这意味着如果你需要根据调度器的当前线程处理一些事情,你将使用InvokeAsync,否则使用BeginInvoke。
编辑: – 但上面的评论是没有意义的,因为你不能改变调度一旦创build相关的线程。
同意上面提到的答案..谢谢