Async / Await: From Zero to Hero
I had absolutely no idea what async / await was and learning it was hard as:
There's 27 minutes wort...
For further actions, you may consider blocking this person and/or reporting abuse
Nice post!
I wanted to add for those who are not that familiar with tasks, that using
ConfigureAwait(false)
is not only about performance issues but also about avoiding deadlocks in UI and Asp.Net applications.In .NET you always should use "ConfigureAwait(false)" if you publish a library.
Second addition:
Using
.Result
within the UI Mainthread or within Asp.Net Request threads produces deadlocks. This also can be avoided usingConfigureAwait(false)
. But care attention if you use dependency injection. The scope may not flow with the code if you useConfigureAwait(false)
.And:
async/await introduces more complexity at CIL level and thus costs memory and CPU time. This should be taken into consideration when writing async code.
When do you decide to use async code?
Hey there, appreciate your helpful insights concerning
ConfigureAwait(false)
. :)You are spot-on concerning this. For the benefit of those reading this comment, this SO post gives 2 examples concerning the added complexity at CIL level when using
async
/await
.I'm not sure if I got your question right, but I suppose you are asking this in relation to the added complexity at CIL level. If so, Stephen Cleary's post provides a thorough explanation on this matter, and I'll summarise some of the key points here:
Which you have mentioned rightly. However,
Stephen Cleary also provides examples of pitfalls, one concerning using the
using
statement, and the other concerning exceptions. He gives an amazing and concise explanation there, so I'll not copy the quotes here.Thanks for your question! You helped me to dig deeper into this topic, which resulted in me finding Stephen's blog post.
Thanks for linking that blog posts. I will read through it. Sounds very interesting!
But what does
ConfigureAwait(false)
do exactly?There isn't an easy answer to this question that doesn't require more explanation. There is an FAQ of sorts here: devblogs.microsoft.com/dotnet/conf...
The very short and condensed version is that it signals to the async system that you want your asynchronous code to not be marshaled back to the original calling context. I highly recommend careful study of the FAQ post for more details on the consequences of that.
I don't use c# outside on my rare unity doodles. In case anyone is familisr with f#, is there anything similar in f# (for the async computational expressiom)?
"The performance of .NET and UI applications can be improved by using ConfigureAwait(false)."
Uuhhh. That's a way more complicated topic than you make it out to be. In a post that spends no time whatsoever talking about synchronization contexts giving such an advice is very illadvised.
Hey there, thanks for pointing out how my statement may be misread! Yes, I'm aware of the complexities involved so I cited Stephen Cleary's answer from SO.
What I really wanted to say is that: You can, but that doesn't mean therefore that you should do it.
Meanwhile, I've removed this statement. Does this convey the message clearer?
Edit: I'll include Cellivar's link as well.
Nice post! I also had troubles approaching async programming, so I wrote an article to help other devs understand the basics of this topic: code4it.dev/blog/asynchronous-prog...
Hey Davide, thanks for reading! I read through your article and found out about the existence of
ValueTask
, thanks for writing!A quick comment on the header
How to make a sync method asynchronous
: Correct me if I'm wrong, I think such a scenario is only helpful when developing Desktop applications, whereby heavy synchronous work should not be processed by the UI thread, but deferred to a background thread usingTask.Run
.Web applications, however, do not have a UI thread. Consider the code samples below (the first is copied from your article)
VS
In both scenarios, a thread is required to perform
DoSomethingSynchronous()
; there's no benefit in doing it in an asynchronous manner. Rather, the asynchronous code would be slightly less performant as it has to deal with the overhead ofasync/await
and allocating Thread B to executeDoSomethingSynchronous()
and freeing Thread A.Edit: I think it's beneficial to run synchronous methods on separate threads using
Task.Run
when executing multiple expensive synchronous methods. For example:VS
In the first option, the methods run sequentially, while the second option has both methods running in parallel, thus the second option should complete earlier than the first option.
Great read and well put together. Thanks for doing this, I would have personaly made the mistake with the make waffle and coffee, then snap a picture, example you gave.
Thank you for your kind encouragement, I'm glad that this post helped you :)
Excellent post. Really well explained.
Thanks Eamon for reading through this article and for your kind words! :)
Nice and clear explanation Zhi Yuan.
Thank you for reading through this article and for your kind words! :)
Nice post
Thank you for your kind encouragement! :)
Thanks for this Zhi, it was a great read, cleared things up quite a bit. I will look into it more for further knowledge.
Hey John, I'm glad that you found this short post helpful! :)