InvokeAsync order

余生颓废 提交于 2019-12-11 01:44:36

问题


I have different scenario, than in this question, therefore another question.

Let's take following example:

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

Invoke creates performance problems. In attempt to fix it I used InvokeAsync in place of Invoke and it seems to work, but it is important what 2 will be output after 1.

Can I rely on assumption what if two InvokeAsync are called from same thread they will execute in the same order? My winapi's nut tells me it's true, but I want to be sure.

And another related question is same as linked one: if same method is called via InvokeAsync action from different threads, how good are chances to have it executed first for thread who calls InvokeAsync earlier?

P.S.: I have feeling question should be rephrased "How InvokeAsync works", but the word "order" is probably 100% candidate of what people (including me) will try to search for.


回答1:


Please, check this out http://referencesource.microsoft.com/#WindowsBase/Base/System/Windows/Threading/Dispatcher.cs,1045

When you call InvokeAsync, an operation is put to PriorityQueue, so I suppose if you call several actions with the same priority, you can be confident that these actions will be executed with the same order.




回答2:


Dispatcher.InvokeAsync() returns a DispatcherOperation object. It has a property Task:

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

You can use all operations a Task supports. For example continue with the second dispatcher call.

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

As Yuval Itzchakov stated, if you simply want to execute them in order, you can await the InvokeAsync call, because DispatcherOperation is awaitable (since it exposes a GetAwaiter method).

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

I would never rely on assumptions on the underlying system. It makes the system fragile (you never really know if that assumption is (still) true).




回答3:


Dispatcher.InvokeAsync returns a DispatcherOperation, which is an awaitable (it exposes a GetAwaiter method). If you want to guarantee execution order, you can await them, in the desired order:

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



回答4:


I have made a conclusion for myself:

Whoever call InvokeAsync first will get its action serviced first.

It has nothing to do with normal async methods uncertainty "who will run first", because implementation of InvokeAsync is a pure thread-safe producer/consumer queue (can be seen in sources, thanks to @olegk answer).



来源:https://stackoverflow.com/questions/32778051/invokeasync-order

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!