Reputation: 21969
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.
Upvotes: 2
Views: 2182
Reputation: 21969
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).
Upvotes: 0
Reputation: 12846
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).
Upvotes: 1
Reputation: 787
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.
Upvotes: 1
Reputation: 149518
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"));
}
Upvotes: 0