Last active
August 29, 2015 14:03
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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