Async2 – The .NET Runtime Async experiment concludes
The .NET team's async2 experiment aims to enhance async/await efficiency by shifting management to the runtime, improving performance and exception handling, but may take years to become production-ready.
Read original articleThe .NET team has concluded its async2 experiment, which aimed to enhance the async/await pattern's efficiency and flexibility by transitioning it from a compiler feature to a runtime feature. Initially, the team explored using green threads, which are lightweight user-space threads, but abandoned this approach due to complexities in interaction with the existing async model, performance issues with native code interop, and compatibility challenges with security measures. The async2 experiment focuses on allowing the runtime to manage async and await, which could lead to improved performance, especially in deep call stacks, and better exception handling. Unlike the current implementation, async2 would not revert changes in the ExecutionContext and SynchronizationContext at function boundaries, allowing for more consistent data flow. The experiment has shown that async2 could outperform the current async model in various scenarios, although it may take years before it is production-ready. The transition will require interoperation between the existing async and the new async2.
- The async2 experiment aimed to improve the efficiency of the async/await pattern in .NET.
- Green threads were initially considered but were abandoned due to various complexities.
- Async2 allows the runtime to manage async/await, potentially improving performance and exception handling.
- The new model will not revert context changes, leading to more consistent data flow.
- Production readiness for async2 may take several years, requiring interop with the current async model.
Related
ECMAScript 2024: What's New?
Ecma International approved ECMAScript 2024 with new features like Promise.withResolvers(), /v flag for Unicode properties, ArrayBuffers enhancements, and Atomics.waitAsync(). Notable additions include resizing ArrayBuffers and string well-formedness methods. A book "Exploring JavaScript (ES2024 Edition)" is available.
Synchronous Core, Asynchronous Shell
A software architecture concept, "Synchronous Core, Asynchronous Shell," combines functional and imperative programming for clarity and testing. Rust faces challenges integrating synchronous and asynchronous parts, prompting suggestions for a similar approach.
Synchronous Core, Asynchronous Shell
Gary Bernhardt proposed a Synchronous Core, Asynchronous Shell model in software architecture, blending functional and imperative programming. Rust faces challenges integrating sync and async functions, leading to a trend of adopting this model for clarity and control.
Ruby Methods Are Colorless
JP Camara discusses colorless methods in Ruby, exploring synchronous and asynchronous functions without explicit color markers. Ruby's Threads and Fibers support seamless, concurrent programming, contrasting with color-coded functions in other languages.
I avoid async/await in JavaScript
Cory argues that async/await complicates JavaScript code, obscures optimization opportunities, increases cognitive load in error handling, and suggests promises are cleaner and more manageable for asynchronous operations.
> Green threads are different. The memory of a green thread is allocated on the heap. But all of this comes with a cost: As they aren't managed by the OS, they can't take advantage of multiple cores inherently. But for I/O-bound operations, they are a good fit.
this is clearly not true? Am I missing some nuance here, as I'm sure the author knows what they're talking about?
Green threads can totally use a multi-threaded runtime, like e.g. Go does, and it works just fine. The main hurdle with them is arguably FFI.
It is difficult to draw conclusions at the present moment on e.g. memory consumption until the work on this, which is underway, makes it into mainline runtime. It's important to understand that the experiment was first and foremost a research to look into modernizing async implementation, and was a massive success. Now once that is proven, the tuned and polished implementation will be made.
Once it is done and makes into a release (it could even be as early as .NET 10), then further review will be possible.
With that said, thank you for writing it, .NET tends to be criminally underrated and slept on by the most of the industry, and these help to alleviate it even if just a bit.
The existing async1/TPL path is stable & predictable. If you find yourself needing more performance, you can reach for hardware Thread instances and use whatever locking/waiting/sharing/context strategies you desire. Anything else is a weird blend of compromises that is going to have caveats that are not immediately obvious for your specific use case.
For example, async2 w/ runtime JIT appears to have some tradeoffs with regard to GC & memory usage and the experiment writeup leaves some open-ended questions here[0].
[0]: https://github.com/dotnet/runtimelab/blob/feature/async2-exp...
For those like me who weren't clear whether `async2` was expected to be a real keyword in the final language, it's not[0].
0 - https://github.com/dotnet/runtime/issues/94620#issuecomment-...
I hope they also revisit task state tracking and TaskCanceledException. It feels out of place to use an exception (and unroll the stack) as control flow in the same API they added ValueTask to keep Task handles on the stack.
So i will try to naievly solve it here, and maybe i end up with the same conclusions.
When doing a blocking call, the OS thread could just start executing something else transparently and not 'yield' anything to the code, it just stops executing the code and comes back and executes further, no await, no tasks no nothing. Ok, but how did we end up in a thread? The http listener started 4 threads and it's just putting a stack of function pointers and context memory for the threads to eat when they want. There is a separate engine on another OS thread that handles where the threads can start executing ready code again. No Task or await keywords show up in this code. I have no idea how stack traces work but i guess that can just be saved to memory and loaded back again when the threads feel like executing some ready code
Related
ECMAScript 2024: What's New?
Ecma International approved ECMAScript 2024 with new features like Promise.withResolvers(), /v flag for Unicode properties, ArrayBuffers enhancements, and Atomics.waitAsync(). Notable additions include resizing ArrayBuffers and string well-formedness methods. A book "Exploring JavaScript (ES2024 Edition)" is available.
Synchronous Core, Asynchronous Shell
A software architecture concept, "Synchronous Core, Asynchronous Shell," combines functional and imperative programming for clarity and testing. Rust faces challenges integrating synchronous and asynchronous parts, prompting suggestions for a similar approach.
Synchronous Core, Asynchronous Shell
Gary Bernhardt proposed a Synchronous Core, Asynchronous Shell model in software architecture, blending functional and imperative programming. Rust faces challenges integrating sync and async functions, leading to a trend of adopting this model for clarity and control.
Ruby Methods Are Colorless
JP Camara discusses colorless methods in Ruby, exploring synchronous and asynchronous functions without explicit color markers. Ruby's Threads and Fibers support seamless, concurrent programming, contrasting with color-coded functions in other languages.
I avoid async/await in JavaScript
Cory argues that async/await complicates JavaScript code, obscures optimization opportunities, increases cognitive load in error handling, and suggests promises are cleaner and more manageable for asynchronous operations.