The reason is the keyword [`yield`][1] which has a specific meaning in C#. On encountering the words `yield return` a function in C# returns, as one would expect. > Using yield to define an iterator removes the need for an explicit extra class >[...] >When a yield return statement is reached in the iterator method, expression is returned, and the current location in code is retained. Execution is restarted from that location the next time that the iterator function is called. So there is no infinite loop. There is a function/iterator that can be called an infinite number of times. The Unity function `StartCoroutine()` makes the Unity framework call the function/iterator once per frame. The Unity function `StopAllCoroutines` makes the Unity framework stop calling the function/iterator. And returning `WaitForSeconds(time)` from the iterator makes the Unity framework suspend calling the function/iterator for `time`. [1]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/yield