3 ms·
async/await makes things complicated - this is a great illustration of some issues with it. Fibers/green threads/goroutines seem to be generally easier and not
by throwaway13337 5y ago
async/await makes things complicated - this is a great illustration of some issues with it. Fibers/green threads/goroutines seem to be generally easier and not viral. C#/dotnet choosing this the async model always bothered me. Otherwise, the platform is solid.
It's interesting, therefore, to try to understand why dotnet went with the async/await model.
A language maintainer C# talks about the issue here and references the rust justification for the same:
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006314.html https://mail.mozilla.org/pipermail/rust-dev/2013-November/00...
https://github.com/dotnet/runtime/issues/11084 https://github.com/dotnet/runtime/issues/11084
They knowingly seem to have chosen a more complicated model for performance. For me, that sounds like a bad trade. Developer time is quite a bit more valuable than compute time. The performance difference just doesn't seem to justify it.
- _old_dude_ 5y agoImplementing coroutine requires to change to the code generator, the runtime and the garbage collectors and there is no general consensus on the way to implement them efficiently => this requires a huge investment in engineering. For Rust, one of the feature of Rust is to have a minimal runtime, so using a compiler transformation seems a good fit. For C#, Microsoft has a limited number of people working on the runtime of DotNet. Async/await was developed at the same time DotNet was transitioning to DotNet Core which also requires massive engineering, so it was about priority. The future will tell if at some point coroutine will be added to DotNet.
- Matthias247 5y agoI think for C# one of the strong async use-cases was the same one as for Javascript having async/await: UI programming. UI environments are mostly single-threaded, and if you want to modify UI elements you have to perform that operation on the UI thread. Doing e.g. a HTTP download in a background thread and directly manipulating a progress bar from there wasn't possible. With async/await that can multiplex all those async tasks onto the UI thread this now gets feasible. With the move to more declarative UI patterns this argument might now get more mood, but I don't have enough recent experience to tell. On the server end, I strongly agree with you that for 95% of applications a threaded environment - and even using plain OS threads - would likely be easier and fast enough. But I guess everyone also wants to support the remaining 5% of applications, like "build a 100k clients proxy server". Btw: Fibers can also be viral. E.g. if they are multiplexed on a single OS thread (non work-stealing scheduler) you still can't block in them, and need fiber-aware methods of everything. If you use a work-stealing scheduler then methods which use thread-local storage might be subject to undefined behavior, because the currrent thread might change inside the execution of the function at an invisible yield point.