Skip to content

Instantly share code, notes, and snippets.

@michaelbartnett
Last active August 29, 2015 14:03
Show Gist options
  • Save michaelbartnett/58959d03a61de982d166 to your computer and use it in GitHub Desktop.
Save michaelbartnett/58959d03a61de982d166 to your computer and use it in GitHub Desktop.
Demonstrates that using MonoBehaviour.StopCoroutine(IEnumerator myCoro) will block forever if other coroutines have yielded myCoro's UnityEngine.Coroutine handle.
using System;
using UnityEngine;
using IEnumerator=System.Collections.IEnumerator;
using System.Collections.Generic;
public class TestDependentCoroStop : MonoBehaviour
{
[SerializeField] bool runTest = false;
void Update()
{
if (runTest) {
runTest = false;
StartCoroutine(RootCoro());
}
}
IEnumerator RootCoro()
{
Debug.Log("RootCoro: start");
// Start the ChildCoro
Debug.Log("RootCoro: yield-waiting for ChildCoro");
IEnumerator childCoroEnumerator = ChildCoro(1f, 1f);
// Let it run its course
yield return StartCoroutine(childCoroEnumerator);
Debug.Log("RootCoro: ChildCoro finished");
// Start another, but keep the Coroutine reference so we can yield it later
Debug.Log("RootCoro: Starting new ChildCoro");
childCoroEnumerator = ChildCoro(1f, 1f);
Coroutine childCoroHandle = StartCoroutine(childCoroEnumerator);
// Now startup a second sub-coroutine. This guy will yield on the child's coroutine
Debug.Log("RootCoro: Starting WaitForChildCoro");
StartCoroutine(WaitForChildCoro(childCoroHandle));
// Yield for 1.5 seconds, since we know the child coroutine has two yields,
// each for 1 second, this should come back right between the child ChildCoro yields.
Debug.Log("RootCoro: Yielding for 1.5 secs (should be between ChildCoro yields)");
yield return new WaitForSeconds(1.5f);
// Now stop ChildCoro before it has a chance to finish.
// This means that WaitForChildCoro's yield will never return.
Debug.Log("RootCoro: Stopping ChildCoro");
StopCoroutine(childCoroEnumerator);
Debug.Log("RootCoro: ChilCoro stopped, RootCoro finished");
}
IEnumerator WaitForChildCoro(Coroutine childCoroHandle)
{
Debug.Log("WaitForChildCoro: Start");
// Yield-wait for the ChildCoro started in RootCoro
Debug.Log("WaitForChildCoro: Yield-waiting for ChildCoro");
yield return childCoroHandle;
// We never reach here
Debug.Log("WaitForChildCoro: ChildCoro finished, WaitForChildCoro finished.");
}
IEnumerator ChildCoro(float wait1, float wait2)
{
Debug.Log("ChildCoro: Start");
Debug.Log("ChildCoro: First Yield");
yield return new WaitForSeconds(wait1);
Debug.Log("ChildCoro: Second Yield");
yield return new WaitForSeconds(wait2);
Debug.Log("ChildCoro: Finished");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment