void ICoroutineRunner.OnUpdate() { if (IsUpdating) { ThrowHelper.InvalidOp("Runnner is already updating"); } IsUpdating = true; List <Exception> exns = null; try { var contCount = _continuations.Count; for (var i = 0; i < contCount; i++) { try { _continuations.Dequeue().Invoke(); } catch (Exception e) { exns ??= new List <Exception>(); exns.Add(e); } } _coroutines.AddRange(_coroutinesTmp); _coroutinesTmp.Clear(); foreach (var c in _coroutines) { if (!c.IsCompleted && !c.IsCanceled) { c.MoveNext(); } if (c.Exception is CanceledException) { // hack Internal.Logger.Log($"CoroutineRunner.OnUpdate {c.GetType().Name} is canceled with {c.Exception.GetType()}"); } else if (c.Exception is Exception e) { Internal.Logger.Log($"CoroutineRunner.OnUpdate {c.GetType().Name} has {e.GetType()}"); exns ??= new List <Exception>(); exns.Add(e); } else if (c.IsCanceled) { Internal.Logger.Log($"CoroutineRunner.OnUpdate {c.GetType().Name} is canceled"); } else if (c.IsCompleted) { Internal.Logger.Log($"CoroutineRunner.OnUpdate {c.GetType().Name} is completed"); } else { _coroutinesTmp.Add(c); } } Count -= (_coroutines.Count - _coroutinesTmp.Count); // Swap (_coroutines, _coroutinesTmp) = (_coroutinesTmp, _coroutines); _coroutinesTmp.Clear(); } finally { IsUpdating = false; } if (exns is { })