InvokeAsync order
本文关键字:order InvokeAsync | 更新日期: 2023-09-27 18:14:34
我有不同的场景,比这个问题,因此另一个问题。
让我们看下面的例子:
void PerformanceCriticalMethod()
{
Dispatcher.Invoke(() => Log.Add("1"));
... some job
Dispatcher.Invoke(() => Log.Add("2"));
}
Invoke
产生性能问题。为了修复它,我使用InvokeAsync
代替Invoke
,它似乎可以工作,但重要的是2
将在 1
之后输出。
InvokeAsync
从同一个线程调用,它们将以相同的顺序执行,我可以依靠假设吗?我的winapi的坚果告诉我这是真的,但我想确定。
和另一个相关的问题是相同的链接一个:如果相同的方法是通过InvokeAsync
行动从不同的线程调用,有多好的机会有它首先执行线程谁调用InvokeAsync
早?
注::我觉得问题应该改为"InvokeAsync是如何工作的",但是"order"这个词可能是人们(包括我)将尝试搜索的100%候选内容。
请查看http://referencesource.microsoft.com/#WindowsBase/Base/System/Windows/Threading/Dispatcher.cs,1045
当您调用InvokeAsync时,一个操作被放到PriorityQueue中,所以我想如果您调用具有相同优先级的几个操作,您可以确信这些操作将以相同的顺序执行。
Dispatcher.InvokeAsync()
返回一个DispatcherOperation
对象。它有一个属性Task
:
获取一个T:System.Threading。表示当前操作的任务。
您可以使用Task
支持的所有操作。例如,继续第二个调度员呼叫。
Dispatcher.InvokeAsync(() => Log.Add("1")).Task.ContinueWith(() => {
Dispatcher.InvokeAsync(() => Log.Add("2"));
});
正如Yuval Itzchakov所说,如果你只是想按顺序执行它们,你可以await
InvokeAsync
调用,因为DispatcherOperation
是awaitable
(因为它公开了GetAwaiter
方法)。
我可以依靠假设,如果两个InvokeAsync从同一线程调用,他们将以相同的顺序执行?
我永远不会依赖于底层系统的假设。它使系统变得脆弱(你永远不知道这个假设是否(仍然)正确)。
Dispatcher.InvokeAsync
返回一个DispatcherOperation
,这是一个可等待对象(它公开了一个GetAwaiter
方法)。如果想要保证执行顺序,可以按照所需的顺序await
它们:
async Task PerformanceCriticalMethodAsync()
{
await Dispatcher.InvokeAsync(() => Log.Add("1"));
... some job
await Dispatcher.InvokeAsync(() => Log.Add("2"));
}
我已经为自己做了一个结论:
谁先调用
InvokeAsync
,谁的动作将首先得到服务。
它与正常的async
方法不确定性"谁将首先运行"无关,因为InvokeAsync
的实现是一个纯线程安全的生产者/消费者队列(可以在源代码中看到,感谢@olegk答案)。