DEV Community

Discussion on: How C# asynchronous programming is different than what you think

Collapse
 
rhymes profile image
rhymes

Hi @vekzdran thanks for the feedback! It took me a while to write the comment haha. I'm thinking I should "upgrade" it to an article.

There is definitely huge effort behind the language and framework design as you state, and it resulted in such a concise and succinct interface. And yes the thread pool is included in the whole problematic, and the key is not to exhaust it with writing bad async/await.

As every technical decision there are advantages and drawbacks. I applaud their decision though, they created a concise interface as you say on top of two complicated mechanisms: asynchronicity and thread pooling.

The clear advantage is that you can utilize more resources of the hosting machine and in the future optimize the pool as you see fit. Maybe they can even in a future version allow the user to inject a "single threaded event handler" for people who don't want to use multiple threads under the hood, but I'm in fantasy land now :D

What I found most in my short experience as a C# developer is that people do not understand what you have excellently pointed out - blocking and yielding control back, that's why often I see code that ignores proper context switching.

That's normal, I think it's because most people learn a form of sequential imperative programming which tends to be blocking. You do A, then B, then C and then you compute the result. That's it. All concurrency model require us programmers to think of what could happen outside of the "main flow".

From the article you linked I read this:

However, you shouldn’t. Because the moment you block on asynchronous code, you’re giving up every benefit of asynchronous code in the first place. The enhanced scalability of asynchronous handlers is nullified as soon as you block a thread.

That's it. If you block too much, the thread is not released to the pool and you slow everything down.

but still one has to take care now of other problems due to implicit parallelism which might occur as a non-easy to observe side effect

Yes, I read the part in the article with the example with a List<string>. The fact that threads are hidden to the user, does not mean all the usual problems magically disappear. I wonder if Rust really nailed it and answered all of these problems with their concept of borrowing. I don't have experience with it, I've read a few articles and in a situation like that the write at the same time (thus losing one of the elements of the list) shouldn't happen because only one thread can have the list reference at any time and that's enforced by their compiler.