As title says, is it possible?
async, await also can replace [ yield return StartCoroutine() ] ?
What is more good between coroutine and async&await?
As title says, is it possible?
async, await also can replace [ yield return StartCoroutine() ] ?
What is more good between coroutine and async&await?
No idea, let us know.
Are you trying to do something useful or just being a C# language aficionado who wants to try all the new stuff?
Coroutines run at specific, known times and safely on the same thread. Asynch may or may not also work that way – there were lots of threads, etc… that you should be able to find with “unity await”.
It can totally replace the Coroutine logic. In fact, async functions give you the real threading ability since it is not relevant to Unity thread. (Coroutines don’t give you the real threading ability since they run in the Unity’s thread). However, async is not practical in my opinion. Because you have to handle every thread by yourself. I suggest using Coroutines. For example; before quitting the game, you have to terminate all async functions by yourself. If you have many async functions this can be a bit complex to track them. You can try this to see it by yourself. Code an async function, and include “wait for 3 seconds” logic in the function. Start the game in editor, and stop the game as soon as the async function is started. After 3 seconds, you will see the editor throws an error even though the game is not running. For Coroutines, you don’t have worry about if Coroutines should be terminated or not, becuase they are terminated automatically when you destroy the related MonoBehavior.
both. C#'s new stuff and higher level grammar, I want to find out thoroughly about, and adopts by result,
whether they are useful? when to use at what exact situations when making game?
why use it? what benefit can be earned by using it rather than not.
code efficiency and reusability, easy readable to other programmers.
They are somewhat different from one another, so it depends on the use case. There are a few bonus points for coroutines:
Meanwhile, async/await allows you write callback-based logic (like I/O tasks) much more cleanly, because that’s what they fundamentally do under the hood: the compiler splits the function at the await points and uses callback mechanisms to hook each part to each awaitable. Code will only be executed when the awaitable completes.
Coroutines are basically a work queue system based on iterators (yield contextual keyword - C# Reference | Microsoft Docs). This article has a good guess at how they work internally: Unity Coroutines: How Do They Work? | gamedevunboxed
This means the active coroutines are checked if they can continue execution every frame, so if you’re doing stuff like web requests, async reading/writing data from/to disk, it’s better to use async/await. However, I find it best to use with non-Unity objects (which can be destroyed and cause your async function to continue straight into a null reference exception).
No async cannot replace coroutines, they function differently as @Neto_Kokku wrote above and the engine will prevent you from doing that completely.
In my quest to get rid of coroutines awhile back when async/await was introduced, I found that I couldn’t fully replace them. I would either not use them at all for what I wanted, was stuck using them because Unity forces me to use them with certain API functionality or restricted from running them on another thread. An example would be changing scenes, it doesn’t give the option to use async/await with SceneManager.LoadSceneAsync. It returns an AsyncOperation which doesn’t have the ability to be awaited on in an async method.
You can have an async method give you an IEnumerator that can be yielded in a coroutine but you cannot have an IEnumerator give you a Task to be awaited on.
Also Task’s generate excess garbage being an object that goes on the heap and async/await has more overhead than Corroutines.
I’ve given up on trying to replace coroutines with async/await. I use them for IO and other async things like some procedural generation so it doesn’t slow down game play(gotta watch for non thread safe Unity functions and don’t touch any GameObject at all.)
Tasks being reference types and ValueTask not being available on Unity is also a problem like you mentioned, but be aware that coroutines also generate garbage due to the use of yield, which creates an implicit state machine class to store continuation data (much like async functions do).
Basically, if you’re concerned about memory allocations and GC spikes you need to forgo most of C#'s fancy stuff. Even lambdas generate garbage.
forgo? forget? maybe?
C# fancy stuff? what exactly the list of it?
Lambdas, Async Await, Linq?, Reflection?, and?
Lambdas only generate if you create a closure. Wich you do uf you access anything else than the input argument to the lambda.
Which is most of the useful part of using lambdas in the first place. There’s very little you can do with them without closures.
Variadic functions (aka: params) allocate an array every time they are called.
String interpolation is also bad, and pretty much string manipulation in general due to C# strings being immutable. StringBuilder helps but there’s always an allocation to produce the final string, so if you have something like a timer display in your game there’s garbage being generated every time it updates.
Interfaces with structs is something that needs to be used with care too, as you can accidentally cause the struct to be boxed.
Idiomatic C# encourages the use of reference types as temporary data. You see it everywhere in Microsoft’s examples, books, tutorials, and other learning resources. Even a lot of Unity’s own APIs follow that pattern, with non-allocating alternatives only being added years later (and there are still some gaps).
This is a great article about things to look out for when trying to reduce or eliminate frame allocations:
Zero allocation code in C# and Unity - Seba’s Lab
There are some alternatives made for Unity: