Reputation: 84
In an attempt to understand async/await I made a little sample WPF application that has one button. When clicked it will do some 'work' :
private async void goButtonClicked(object sender, EventArgs e)
{
WhatThreadAmI();
var task = populateRawData().ConfigureAwait(false);
WhatThreadAmI();
BusyIndicator.IsBusy = true;
await task;
WhatThreadAmI(); //this isnt on the main thread - why??
BusyIndicator.IsBusy = false;
Console.WriteLine("fin");
}
The "WhatThreadAmI" simply compares the current thread to the UI thread which I save on initialization.
public bool IsMainThread => uiThread == Thread.CurrentThread;
I expected the output of this to be True - True - True, with the "WhatThreadAmI" call in the populate raw data method to return false.
What actually happens is True - True - False, with the ""WhatThreadAmI" call in the populate raw data method returning true.
I know I must be missing something very fundamental here, but can someone please help me understand what is going on?
Upvotes: 3
Views: 247
Reputation: 457187
var task = populateRawData().ConfigureAwait(false);
ConfigureAwait(false)
returns a configured task awaiter that does not resume on a captured context. I explain how await
captures and resumes on context in detail on my blog; the usage of ConfigureAwait(false)
means to not capture and resume on the context. In this case, the "context" is the UI thread. So, the await
doesn't resume of the UI thread because the ConfigureAwait(false)
is explicitly telling the await
that it doesn't need to.
On a side note, the task
variable in that code does not contain a Task
. It's extremely unusual to have the result of ConfigureAwait
in a variable instead of with its await
. The following example is equivalent and - I think - expresses more clearly what's going on:
WhatThreadAmI();
var task = populateRawData();
WhatThreadAmI();
BusyIndicator.IsBusy = true;
await task.ConfigureAwait(false);
WhatThreadAmI(); //this isnt on the main thread - why??
BusyIndicator.IsBusy = false;
Put another way: it's ConfigureAwait
, not ConfigureTask
. It doesn't change the task at all; ConfigureAwait
only makes sense to use with await
.
Upvotes: 4
Reputation: 1
change ConfigureAwait(false); to ConfigureAwait(true); or just remove it.
Upvotes: -1
Reputation: 26516
the Task
object is an abstraction over the .Net Thread pool. one thread may begin executing code, await a not-finished task, and be resumed from a different thread.
in this way you can maximize the use of your CPU without blocking. threads have no meaning to tasks. an available thread will continue your task execution when awaiting is finished. it may be the thread which executed the task in the past, it may not.
Upvotes: 0