|
|
|
|
|
by Matthias247
2748 days ago
|
|
Yes, the state machine generation aspect is similar. However the execution aspect is a bit different: In C#, once a leaf future/Task gets resolved, it will in many cases sychronously call back into the state machine which awaited the task Task (by storing a continuation inside it). A whole promise chain might resolve synchronously directly on the stack of the caller. And "in many cases", because the whole thing depends on some very subtle properties like whether a SynchronizationContext or TaskScheduler was configured. In Rusts task system a leaf future will never call back into the parent. It will always only notify the associated task executor, that it can retry running/polling the Future to completion. When the task gets executed again, it will run again from the normal scheduler thread in a top-down fashion. This makes Rusts system a little less performant for some use-cases, but also a lot less error-prone (no synchronization issues because it's not known where some code runs). It also is one of the key ingredients for avoiding allocations on individual futures. Javascripts system is closer to the C# mechanism, but avoids the error-prone part: When a leaf future is finished, it will lead to calling the continuation of the parent future. However this is never done synchronously, but always on a fresh iteration of the eventloop (to avoid side effects). That works fine for Javascript because the eventloop is guaranteed (it's not in C# async code), and Futures are on the heap anyway. |
|