InvokeAsync 命令

InvokeAsync order

我的场景与 this question 不同,因此又是一个问题。

让我们举个例子:

void PerformanceCriticalMethod()
{
    Dispatcher.Invoke(() => Log.Add("1"));
    ... some job
    Dispatcher.Invoke(() => Log.Add("2"));
}

Invoke 造成性能问题。为了修复它,我使用 InvokeAsync 代替 Invoke,它 似乎有效 ,但重要的是 2 将被输出 之后 1.

如果从同一个线程调用两个 InvokeAsync,它们将以相同的顺序执行,我可以假设吗?我的 winapi 的 nut 告诉我这是真的,但我想确定一下。

另一个相关问题与链接的问题相同:如果通过来自不同线程的 InvokeAsync 操作调用相同的方法,那么较早调用 InvokeAsync 的线程首先执行它的机会有多大?

P.S.: 我觉得问题应该改写 "How InvokeAsync works",但是 "order" 这个词可能是人们(包括我)将尝试搜索的内容的 100% 候选者.

Dispatcher.InvokeAsync() returns 一个 DispatcherOperation 对象。它有一个 属性 Task:

Gets a T:System.Threading.Task that represents the current operation.

您可以使用 Task 支持的所有操作。例如继续第二个调度程序调用。

Dispatcher.InvokeAsync(() => Log.Add("1")).Task.ContinueWith(() => {
    Dispatcher.InvokeAsync(() => Log.Add("2"));
});

正如 Yuval Itzchakov 所说,如果你只是想按顺序执行它们,你可以 await InvokeAsync 调用,因为 DispatcherOperationawaitable(因为它公开了一个 GetAwaiter 方法)。

Can I rely on assumption what if two InvokeAsync are called from same thread they will execute in the same order?

我绝不会依赖对底层系统的假设。它使系统变得脆弱(你永远不知道这个假设是否(仍然)正确)。

Dispatcher.InvokeAsync returns a DispatcherOperation, which is an awaitable (it exposes a GetAwaiter 方法)。如果你想保证执行顺序,你可以await他们,按照想要的顺序:

async Task PerformanceCriticalMethodAsync()
{
    await Dispatcher.InvokeAsync(() => Log.Add("1"));
    ... some job
    await Dispatcher.InvokeAsync(() => Log.Add("2"));
}

请检查一下http://referencesource.microsoft.com/#WindowsBase/Base/System/Windows/Threading/Dispatcher.cs,1045

当您调用 InvokeAsync 时,会将一个操作放入 PriorityQueue,因此我想如果您以相同的优先级调用多个操作,您可以确信这些操作将以相同的顺序执行。

我自己得出结论:

Whoever call InvokeAsync first will get its action serviced first.

它与正常的async方法不确定性"who will run first"无关,因为InvokeAsync的实现是一个纯线程安全的producer/consumer队列(可以在sources,感谢@olegk 的回答)。