Example #1
0
        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();
        }
Example #2
0
        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);
            }
        }
Example #4
0
        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);
        }
Example #5
0
        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);
        }
Example #7
0
        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);
        }
Example #8
0
        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);
        }
Example #9
0
        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);
        }
Example #10
0
        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);
        }
Example #11
0
        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);
        }
Example #12
0
        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());
        }
Example #15
0
        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());
        }
Example #16
0
        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);
        }
Example #17
0
        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());
        }
Example #18
0
        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);
        }
Example #19
0
        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);
        }
Example #20
0
        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);
        }
Example #21
0
        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);
        }
Example #22
0
        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);
        }
Example #23
0
        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);
        }
Example #24
0
        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);
        }
Example #25
0
        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);
        }
Example #26
0
        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);
        }
Example #27
0
        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);
        }
Example #29
0
        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);
        }
Example #30
0
        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);
                }
            }
        }