protected static IEnumerator CoroutinesRunner(ThreadSafeQueue <PausableTask> newTaskRoutines, FasterList <PausableTask> coroutines, FlushingOperation flushingOperation, RunningTasksInfo info, FlushTasksDel flushTaskDel, RunnerBehaviour runnerBehaviourForUnityCoroutine = null) { while (true) { if (flushingOperation.waitForflush == false) //don't start anything while flushing { flushTaskDel(newTaskRoutines, coroutines, flushingOperation); } info.count = coroutines.Count; for (int i = 0; i < info.count; i++) { var enumerator = coroutines[i]; try { //let's spend few words about this. Special YieldInstruction can be only processed internally //by Unity. The simplest way to handle them is to hand them to Unity itself. //However while the Unity routine is processed, the rest of the coroutine is waiting for it. //This would defeat the purpose of the parallel procedures. For this reason, the Parallel //routines will mark the enumerator returned as ParallelYield which will change the way the routine is processed. //in this case the MonoRunner won't wait for the Unity routine to continue processing the next tasks. var current = enumerator.Current; PausableTask enumeratorToHandle = null; var yield = current as ParallelYield; if (yield != null) { current = yield.Current; } else { enumeratorToHandle = enumerator; } if (runnerBehaviourForUnityCoroutine != null) { if (current is YieldInstruction || current is AsyncOperation) { runnerBehaviourForUnityCoroutine.StartCoroutine(HandItToUnity(current, enumeratorToHandle, newTaskRoutines, flushingOperation)); if (enumeratorToHandle != null) { coroutines.UnorderredRemoveAt(i--); info.count = coroutines.Count; continue; } } } bool result; #if TASKS_PROFILER_ENABLED && UNITY_EDITOR result = Tasks.Profiler.TaskProfiler.MonitorUpdateDuration(enumerator); #else result = enumerator.MoveNext(); #endif if (result == false) { var disposable = enumerator as IDisposable; if (disposable != null) { disposable.Dispose(); } coroutines.UnorderredRemoveAt(i--); } } catch (Exception e) { string message = "Coroutine Exception: "; Utility.Console.LogException(new CoroutineException(message, e)); coroutines.UnorderredRemoveAt(i--); } info.count = coroutines.Count; } if (flushingOperation.waitForflush == true && coroutines.Count == 0) { //this process is more complex than I like, not 100% sure it covers all the cases yet flushingOperation.waitForflush = false; flushingOperation.stopped = false; } yield return(null); } }