B
B
beduin012019-01-24 12:18:54
go
beduin01, 2019-01-24 12:18:54

Is there a difference between goroutines and await in C#?

Is there a fundamental difference between goroutines and async-await syntax constructs in C#?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
T
Tyranron, 2019-01-25
@beduin01

While these tools are designed to solve the same problems, they do so differently, both under the hood and in terms of the abstractions they offer. Therefore, it cannot be said that async/await in C# is "just a wrapper over goroutines".
Goroutines in Go are the concept of stackful coroutines (under the hood) + CSP (in abstractions). Every time we create a goroutine, a separate call stack is allocated for it for its own needs. At the same time, when a panic occurs, then stack unwinding (unwinding of the call stack) occurs only within this goroutine and does not leave the boundaries of its stack. The stack of a goroutine is completely decoupled from its creation/call stack, so a goroutine cannot return a result. Any communication between goroutines is done either through channels or some kind of shared memory.
async/await in C# (i.e., Task 's) is the concept of stackless coroutines (under the hood) + futures (in abstractions). The compiler turns code with async/await into a specific state machine with yield points. They do not have a separate stack, they run on the same stack as the code that calls them. Accordingly, it is possible to catch exceptions (analogous to panics) arising inside an asynchronous Task right in the code that launches it. Since the execution goes on the same stack, Task can normally return a result and we can read it in the calling code without additional primitives / tools.
However, if we start Go withGOMAXPROCS=1, then we get single-threaded asynchronous code in Go (it is multi-threaded by default). Also in C#, we can execute Tasks both on a single thread and on a thread pool, getting runtime guarantees similar to Go.
From the point of view of abstractions / use - this is already a matter of taste. Who likes it better. Futures have a better design in terms of composability (they are more ergonomic than join'it and select'it), but they force you to write async and await everywhere. Goroutines need to constantly mess with synchronization (try to make an analogue of await for an arbitrary goroutine), but if this leapfrog is hidden under the hood (as they usually do), then the code generally looks completely synchronous and programmers are happy.

V
Vyacheslav Zolotov, 2019-01-24
@SZolotov

After the goroutine is called, execution will immediately jump to the next line without waiting for the called function to complete. The await keyword indicates that you need to wait until the called function returns the result and only then proceed to the execution of the next line.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question