InvokeAsync订单

时间:2015-09-25 08:34:11

标签: c# multithreading invoke

我有不同的情景,而不是this question,因此另一个问题。

我们采取以下示例:

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

Invoke会产生性能问题。在尝试修复它时,我使用InvokeAsync代替Invoke并且似乎正常工作,但重要的是2将输出之后 1

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

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

P.S。:我感觉问题应该被重新定义&#34; InvokeAsync如何运作&#34;,但是单词&#34; order&#34;可能是人们(包括我)试图搜索的人的100%候选人。

4 个答案:

答案 0 :(得分:1)

Dispatcher.InvokeAsync()会返回DispatcherOperation个对象。它有一个属性Task

  

获取表示当前操作的T:System.Threading.Task。

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

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

正如Yuval Itzchakov所说,如果你只是想按顺序执行它们,你可以await InvokeAsync来电,因为DispatcherOperationawaitable(因为它暴露了GetAwaiter方法)。

  

我可以依赖于假设如果从同一个线程调用两个InvokeAsync,它们将以相同的顺序执行吗?

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

Dispatcher.InvokeAsync返回DispatcherOperation,这是一个等待的(它公开了GetAwaiter方法)。如果您想保证执行顺序,可以按所需顺序await

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

答案 3 :(得分:0)

我已经为自己做了一个结论:

  

首先致电InvokeAsync的人将首先获得服务。

它与普通async方法不确定性“谁将首先运行”无关,因为InvokeAsync的实现是一个纯线程安全的生产者/消费者队列(可以在{{3中看到)感谢@olegk回答)。