Rust Wiki



If you are already familiar with CSharp you may have heard of Async and Task. If so, skip ahead to Coroutines Vs Async.

What is Async?

Lets say you need to make a web request to a remote server and it takes 1 second to respond. If you were to use synchronous code (where every instruction runs one after the other) your program would freeze for 1 full second waiting for the response.

This might not be a problem for some small program that runs in the background but this is a massive problem for a game server where a server lag spike will anger players.

What do we do?

Luckily there is a solution: Async coding.

This allows you to run the web request in the background.

While the web request is being processed the code that does not depend on the result of the web request will continue to execute.

When used correctly this prevents slow actions from freezing your program. Examples include:

  • Web Requests
  • File Reads / Writes
  • Database Access
  • Etc

However, there is one 'gotcha' with Async...

Coroutines Vs Async

Async can be made to run on a separate thread, but by default will run on the main thread.

Coroutines always run on the main thread meaning it is safe and no extra considerations need to be taken

Beyond the usual dangers when multi-threading, Unity will throw an error if you try to use any unity functions from a separate thread.

Coroutines are almost always required when splitting up work over multiple frames.

How do I use them?

public IEnumerator CoroutineExample() { //Wait one frame yield return null; Console.WriteLine( "Inside the main coroutine" ); //Split up a loop over multiple frames for(int i = 0; i < 1000; i++) { Console.WriteLine( "Currently on loop #" + i.ToString() ); //Wait every 100 loops if (i % 100 == 0) { //Wait one full second yield return WaitForSeconds(1); } } //Run the second coroutine and wait for it to finish yield return Coroutine2(); //Function will finish normally } public IEnumerator Coroutine2() { }

Let go over each part of the function above.


Type that can be looped over to return values one by one.

yield return _____

Return an item and continue executing the function

yield return break

Return nothing but stop execution of the program

yield return null

Return a null value and continue execution the function

This means wait for a single frame before continuing execution