The reason is the keyword yield
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
.
A confused comment and an equally confused upvote on that comment encouraged me to elaborate further on what the keyword yield
does and doesn't do.
If you write this:
IEnumerable<int> Count()
{
int i = 0;
yield return i++;
}
You can instead also write this:
IEnumerator<int> Count() {
return new CountEnumerator ();
}
class CountEnumerator : IEnumerator<int> {
int i = 0;
bool IEnumerator<int>.MoveNext() { i++; return true; }
int IEnumerator<int>.Current { get { return i; }
void IEnumerator<int>.Reset() { throw new NotSupportedException(); }
}
It follows that the keyword yield
is not related to multi-threading and does absolutely not call System.Threading.Thread.Yield()
.