public void 実行途中のタスクを再スタートしようとしたら例外を出す() { var x = 10.0; var task = new Task <double>(c => Coroutines.F1Async(x, c)); Assert.AreEqual(TaskStatus.Created, task.Status); var runnner = new SampleTaskRunner.TaskRunner(); task.Start(runnner); runnner.Update(); Assert.AreEqual(TaskStatus.Running, task.Status); try { task.Start(runnner); } catch (InvalidOperationException) { return; } Assert.Fail(); }
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); } }
public void 開始前_実行中_正常終了_エラー終了_キャンセルされた_がわかる() { var x = 10.0; var task = new Task <double>(c => Coroutines.F1Async(x, c)); Assert.AreEqual(TaskStatus.Created, task.Status); var runnner = new SampleTaskRunner.TaskRunner(); task.Start(runnner); runnner.Update(); Assert.AreEqual(TaskStatus.Running, task.Status); runnner.Update(10); Assert.AreEqual(TaskStatus.RanToCompletion, task.Status); var errorTask = new Task(Coroutines.FErrorAsync); Assert.AreEqual(TaskStatus.Created, errorTask.Status); errorTask.Start(runnner); runnner.Update(); Assert.AreEqual(TaskStatus.Running, errorTask.Status); runnner.Update(10); Assert.AreEqual(TaskStatus.Faulted, errorTask.Status); }
private IEnumerator Await5Frame(Action <int> completedFrameCount) { var s = Task.DefaultScheduler.UpdateCount; yield return(Coroutines.NFrame(5)); completedFrameCount(Task.DefaultScheduler.UpdateCount - s); }
public void キャンセルトークンを渡しても_Cancelを呼ばなければ正常終了() { var x = 10; var scheduler = Task.DefaultScheduler; var t = Task.Run <double>(c => Coroutines.F1Cancelable(x, 20, c, CancellationToken.None)); while (!t.IsCompleted) { scheduler.Update(); } Assert.AreEqual(Coroutines.F1(x), t.Result); }
public void Task_Tで正常終了するとResultに結果が入る() { var x = 10; var y = Coroutines.F1(x); var task = Task.Run <double>(c => Coroutines.F1Async(x, c)) .OnComplete(t => Assert.AreEqual(t.Result, y)); var scheduler = Task.DefaultScheduler; scheduler.Update(10); Assert.AreEqual(y, task.Result); }
public void Task_Tで正常終了するとResultに結果が入る() { var x = 10; var y = Coroutines.F1(x); var task = new Task <double>(c => Coroutines.F1Async(x, c)) .OnComplete(t => Assert.AreEqual(t.Result, y)); var runnner = new SampleTaskRunner.TaskRunner(); task.Start(runnner); runnner.Update(10); Assert.AreEqual(y, task.Result); }
public void キャンセルトークンを渡しても_Cancelを呼ばなければ正常終了() { var x = 10; var runner = new SampleTaskRunner.TaskRunner(); var t = new Task <double>(c => Coroutines.F1Cancelable(x, 20, c, CancellationToken.None)); t.Start(runner); while (!t.IsCompleted) { runner.Update(); } Assert.AreEqual(Coroutines.F1(x), t.Result); }
public void 一度完了したタスク_何度でも結果が取れる() { var x = 10; var y = Coroutines.F1(x); var task = Task.Run <double>(c => Coroutines.F1Async(x, c)); var scheduler = Task.DefaultScheduler; scheduler.Update(10); Assert.AreEqual(y, task.Result); Assert.AreEqual(y, task.Result); Assert.AreEqual(y, task.Result); Assert.AreEqual(y, task.Result); }
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 一度完了したタスク_何度でも結果が取れる() { var x = 10; var y = Coroutines.F1(x); var task = new Task <double>(c => Coroutines.F1Async(x, c)); var runnner = new SampleTaskRunner.TaskRunner(); task.Start(runnner); runnner.Update(10); Assert.AreEqual(y, task.Result); Assert.AreEqual(y, task.Result); Assert.AreEqual(y, task.Result); Assert.AreEqual(y, task.Result); }
public void CancellationTokenを使うバージョンのRunでタスク開始するとTask_Cancel可能() { var x = 10; var scheduler = Task.DefaultScheduler; var cts = new CancellationTokenSource(); var t = Task.Run <double>((c, ct) => Coroutines.F1Cancelable(x, 20, c, ct), cts); scheduler.Update(5); t.Cancel(); // 次の1回の実行でタスクが終わるはず scheduler.Update(); // この場合は IsCanceled にならない Assert.IsTrue(t.IsFaulted); Assert.AreEqual(typeof(TaskCanceledException), t.Exception.Exceptions.Single().GetType()); }
public void キャンセルしたときにOperationCanceld例外発生() { var x = 10; var scheduler = Task.DefaultScheduler; var cts = new CancellationTokenSource(); var t = Task.Run <double>(c => Coroutines.F1Cancelable(x, 20, c, cts.Token)); scheduler.Update(5); cts.Cancel(); // 次の1回の実行でタスクが終わるはず scheduler.Update(); // この場合は IsCanceled にならない Assert.IsTrue(t.IsFaulted); Assert.AreEqual(typeof(TaskCanceledException), t.Exception.Exceptions.Single().GetType()); }
public void TaskにCancellationTokenSourceを渡しておいて_TaskのCancelメソッド経由でキャンセルできる() { var x = 10; var runner = new SampleTaskRunner.TaskRunner(); var cts = new CancellationTokenSource(); var t = new Task <double>(c => Coroutines.F1Cancelable(x, 20, c, cts.Token)); t.Cancellation = cts; t.Start(runner); runner.Update(5); t.Cancel(); // Task.Cancel の中で1度 MoveNext して、即座にキャンセル処理が動くようにする // 挙動自体は cts.Cancel(); と同じ Assert.IsTrue(t.IsFaulted); Assert.AreEqual(typeof(TaskCanceledException), t.Error.Exceptions.Single().GetType()); }
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 キャンセルしたときにOperationCanceld例外発生() { var x = 10; var runner = new SampleTaskRunner.TaskRunner(); var cts = new CancellationTokenSource(); var t = new Task <double>(c => Coroutines.F1Cancelable(x, 20, c, cts.Token)); t.Start(runner); runner.Update(5); cts.Cancel(); // 次の1回の実行でタスクが終わるはず runner.Update(); // この場合は IsCanceled にならない Assert.IsTrue(t.IsFaulted); Assert.AreEqual(typeof(TaskCanceledException), t.Error.Exceptions.Single().GetType()); }
public void タスク完了時にContinueWithが呼ばれる() { var x = 10; var y = Coroutines.F1(x); bool called = false; var task = Task.Run <double>(c => Coroutines.F1Async(x, c)); task.ContinueWith(t => called = true); Assert.IsFalse(called); var scheduler = Task.DefaultScheduler; scheduler.Update(10); Assert.IsTrue(called); }
public void ContinueWithで継続処理を実行できる() { var x = 10.0; var x1 = Coroutines.F1(x); var x2 = Coroutines.F2(x1); var x3 = Coroutines.F3(x2); var task = Task.Run <double>(c => Coroutines.F1Async(x, c)) .OnComplete(t => Assert.AreEqual(t.Result, x1)) .ContinueWithIterator <string>((t, callback) => Coroutines.F2Async(t.Result, callback)) .OnComplete(t => Assert.AreEqual(t.Result, x2)) .ContinueWithIterator <int>((t, callback) => Coroutines.F3Async(t.Result, callback)) .OnComplete(t => Assert.AreEqual(t.Result, x2)) ; var scheduler = Task.DefaultScheduler; scheduler.Update(30); }
public void 完了済みのタスクでOnCompleteすると_即座にコールバックが呼ばれる() { var runnner = new SampleTaskRunner.TaskRunner(); var x = 10; var y = Coroutines.F1(x); var task = new Task <double>(c => Coroutines.F1Async(x, c)); task.Start(runnner); runnner.Update(10); Assert.IsTrue(task.IsCompleted); bool called = false; task.OnComplete(t => called = true); Assert.IsTrue(called); }
public void 完了済みのタスクでContinueWithすると_次のUpdateでコールバックが呼ばれる() { var x = 10; var y = Coroutines.F1(x); var task = Task.Run <double>(c => Coroutines.F1Async(x, c)); var scheduler = Task.DefaultScheduler; scheduler.Update(10); Assert.IsTrue(task.IsCompleted); bool called = false; task.ContinueWith(t => called = true); scheduler.Update(); Assert.IsTrue(called); }
public void ContinueWithで継続処理を実行できる() { var x = 10.0; var x1 = Coroutines.F1(x); var x2 = Coroutines.F2(x1); var x3 = Coroutines.F3(x2); var task = new Task <double>(c => Coroutines.F1Async(x, c)) .OnComplete(t => Assert.AreEqual(t.Result, x1)) .ContinueWith <string>(Coroutines.F2Async) .OnComplete(t => Assert.AreEqual(t.Result, x2)) .ContinueWith <int>(Coroutines.F3Async) .OnComplete(t => Assert.AreEqual(t.Result, x2)) ; var runner = new SampleTaskRunner.TaskRunner(); task.Start(runner); runner.Update(20); }
public void 開始前_実行中_正常終了_エラー終了_がわかる() { var scheduler = Task.DefaultScheduler; var x = 10.0; var task = Task.Run <double>(c => Coroutines.F1Async(x, c)); Assert.AreEqual(TaskStatus.Running, task.Status); scheduler.Update(10); Assert.AreEqual(TaskStatus.RanToCompletion, task.Status); var errorTask = Task.Run(Coroutines.FErrorAsync); Assert.AreEqual(TaskStatus.Running, errorTask.Status); scheduler.Update(10); Assert.AreEqual(TaskStatus.Faulted, errorTask.Status); }
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 TaskのForceCancelで強制的にタスクを止めたときはOnCompleteも呼ばれない() { var x = 10; var runner = new SampleTaskRunner.TaskRunner(); var cts = new CancellationTokenSource(); var t = new Task <double>(c => Coroutines.F1Cancelable(x, 20, c, cts.Token)); t.OnComplete(_ => { Assert.Fail(); }); t.Start(runner); runner.Update(5); t.ForceCancel(); runner.Update(); // この場合は IsCanceled に Assert.IsTrue(t.IsCanceled); }
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 実行途中のタスクを再スタートしようとしたら例外を出す() { var x = 10.0; var task = Task.Run <double>(c => Coroutines.F1Async(x, c)); var scheduler = Task.DefaultScheduler; scheduler.Update(); Assert.AreEqual(TaskStatus.Running, task.Status); try { task.Start(); } catch (InvalidOperationException) { return; } Assert.Fail(); }
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); }
public void new_Taskでコールドスタート_Task_Runでホットスタート() { var x = 10; var t1 = new Task <double>(c => Coroutines.F1Async(x, c)); Assert.AreEqual(TaskStatus.Created, t1.Status); t1.Start(); Assert.AreEqual(TaskStatus.Running, t1.Status); var t2 = Task.Run <double>(c => Coroutines.F1Async(x, c)); Assert.AreEqual(TaskStatus.Running, t2.Status); var scheduler = Task.DefaultScheduler; scheduler.Update(10); Assert.AreEqual(TaskStatus.RanToCompletion, t1.Status); Assert.AreEqual(TaskStatus.RanToCompletion, t2.Status); }
public void Nフレーム実行するイテレーターが丁度N引く1フレームIsCompleted_falseになってることを確認() { // 開始直後に RunOnce する仕様になったので、Update ループ回数は1少ない const int N = 50; var task = Coroutines.NFrameTask(N); var scheduler = Task.DefaultScheduler; for (int i = 0; i < 2 * N; i++) { scheduler.Update(); if (i < N) { Assert.IsFalse(task.IsCompleted, "expected false, but actual true on i = " + i); } else { Assert.IsTrue(task.IsCompleted, "expected true, but actual false on i = " + i); } } }