I have a small project - WinForms On .net frameWork - just a small test :
private void button9_Click(object sender, EventArgs e)
{
    string text = GetTitleAsync().Result;
    button9.Text = text;            
}
private async Task<string> GetTitleAsync()
{
    await Task.Delay(3000);
    return "Hello!";
}
As I ran the application , Clicking the button: "button9" - caused a dead lock, (since the thread was hung on the ".result" )
Writing GetTitleAsync() this way:
private async Task<string> GetTitleAsync()
{
    await Task.Delay(3000).ConfigureAwait(false);
    return "Hello!";
}
solved the deadlock - and the application ran ok.
But I don't understand how ?
I would have expected, that using ".ConfigureAwait(false)" would cause a situation in which :
"button9.Text = text;" is executed on a different thread than the one, on which the UI was created, and an excpetion would be throwed !
but it works excellent ! how??
 
                        
I recommend reading my
async/awaitintro; I try to include everything you need to know aboutasync/awaitand their contexts, without getting into too much detail for an intro.Specifically, there are two points from that post that are worth noting:
asyncmethod begins executing synchronously, on the calling thread.awaitcaptures a context unless you useConfigureAwait(false).So, walking through this code:
This is what happens, in order, with special attention paid to which thread runs which code:
button9_ClickcallsGetTitleAsync()on the UI thread.GetTitleAsync()callsTask.Delay(3000)and gets back a task that will complete in 3 seconds.GetTitleAsync()callsConfigureAwait(false)and gets back a configured awaiter that will not resume on the current (UI) context.GetTitleAsync()usesawaitto asynchronously wait for the task to complete. Thisawaitwill not resume on the current (UI) context because theawaithas been configured not to.awaitexamines the task and sees it is not complete, so it returns an incompleteTask<string>to its caller.button9_Clickcalls.Resulton that task. This blocks the UI thread until that task completes (i.e.,GetTitleAsync()is finished executing).Task.Delay(3000)completes.GetTitleAsync()resumes executing after itsawait. Since this was a configuredawait, it continues executing on a thread pool thread.GetTitleAsync()returns"Hello!". This is done on a thread pool thread.GetTitleAsync()is now complete, and theTask<string>that it returned earlier is now completed with a result value. This completion also happens on a thread pool thread.button9_Click.button9_Clickexecutesbutton9.Text = text;on the UI thread.