private IEnumerator WhenAnyで何か1つのタスクが終わるのを待てるIterator() { var delays = new[] { 3, 5, 7, 9, 11, 13 }; var tasks = delays.Select(d => Task.Run(() => Coroutines.NFrame(d))).ToArray(); while (true) { var task = Task.WhenAny(tasks); yield return(task); var first = task.Result; // delays が昇順で並んでいるので、前のタスクから終わるはず Assert.AreEqual(first, tasks[0]); // delays に同じ値を入れていないので、同時に1個ずつしか終わらないはず foreach (var t in tasks.Skip(1)) { Assert.IsFalse(t.IsCompleted); } // 終わったやつを除外。全部終わったら終了 tasks = tasks.Where(t => t != first).ToArray(); if (tasks.Length == 0) { break; } } }
private IEnumerator yield_returnでawait的なことができるIterator(int maxDelay, TaskSchedulerHelper s) { var random = new Random(); int n = random.Next(19, maxDelay); var tasks = Enumerable.Range(0, 5).Select(_ => Task.Run(Coroutines.NFrame(n))).ToArray(); foreach (var t in tasks) { if (t.IsCompleted) { // 完了済みのタスクを yield return すると、1フレーム後にすぐ戻ってくるはず var countBefore = s.FrameCount; yield return(t); var countAfter = s.FrameCount; Assert.AreEqual(countBefore + 1, countAfter); } else { yield return(t); // yield return するとタスク完了待てる Assert.IsTrue(t.IsCompleted); } } foreach (var t in tasks) { Assert.IsTrue(t.IsCompleted); } }
private IEnumerator Await5Frame(Action <int> completedFrameCount) { var s = Task.DefaultScheduler.UpdateCount; yield return(Coroutines.NFrame(5)); completedFrameCount(Task.DefaultScheduler.UpdateCount - s); }
public void OnCompleteは_直前のタスク完了時_エラーも正常終了も_どちらも呼ばれる() { var errorTaskCalled = false; var normalTaskCalled = false; var normalTask = Task.Run(() => Coroutines.NFrame(5)) .OnComplete(t => normalTaskCalled = true); var errorTask = Task.Run <int>(Coroutines.FErrorAsync) .OnComplete(t => errorTaskCalled = true); var scheduler = Task.DefaultScheduler; scheduler.Update(20); Assert.IsTrue(normalTaskCalled); Assert.IsTrue(errorTaskCalled); }
public void OnCompleteは_直前のタスク完了時_エラーも正常終了も_どちらも呼ばれる() { var errorTaskCalled = false; var normalTaskCalled = false; var normalTask = new Task(() => Coroutines.NFrame(5)) .OnComplete(t => normalTaskCalled = true); var errorTask = new Task <int>(Coroutines.FErrorAsync) .OnComplete(t => errorTaskCalled = true); var runner = new SampleTaskRunner.TaskRunner(); errorTask.Start(runner); normalTask.Start(runner); runner.Update(20); Assert.IsTrue(normalTaskCalled); Assert.IsTrue(errorTaskCalled); }
public void WhenAllでタスクの並行動作できる() { var t1 = Task.Run(() => Coroutines.NFrame(3)); var t2 = Task.Run(() => Coroutines.NFrame(5)); var t3 = Task.Run(() => Coroutines.NFrame(7)); var task = Task.WhenAll(t1, t2, t3) .OnComplete(t => { Assert.IsTrue(t1.IsCompleted); Assert.IsTrue(t2.IsCompleted); Assert.IsTrue(t3.IsCompleted); }); var scheduler = Task.DefaultScheduler; scheduler.Update(20); Assert.IsTrue(task.IsCompleted); Assert.IsNull(task.Exception); }
public void WhenAllでタスクの並行動作できる() { var t1 = new Task(() => Coroutines.NFrame(3)); var t2 = new Task(() => Coroutines.NFrame(5)); var t3 = new Task(() => Coroutines.NFrame(7)); var task = Task.WhenAllTask(t1, t2, t3) .OnComplete(t => { Assert.IsTrue(t1.IsCompleted); Assert.IsTrue(t2.IsCompleted); Assert.IsTrue(t3.IsCompleted); }); var runner = new SampleTaskRunner.TaskRunner(); task.Start(runner); runner.Update(20); Assert.IsTrue(task.IsCompleted); }
public void タスク完了と同フレームでContinueWithが呼ばれる() { var random = new Random(); int n = random.Next(10, 300); var scheduler = new TaskSchedulerHelper(Task.DefaultScheduler); int count = 0; var t1 = Task.Run(() => Coroutines.NFrame(n)) .ContinueWith((_) => count = scheduler.FrameCount); for (var i = 0; i < 10000; ++i) { scheduler.Update(); if (t1.IsCompleted) { Assert.AreEqual(n, i); break; } } Assert.AreEqual(n, count); }