Beispiel #1
0
        public void RunnerScopePropagatesToCalledMethods()
        {
            var count = 0;

            using (var runner = new LocalTaskRunner(this.exceptionHandler))
            {
                var t = runner.StartTask(TestAsync);
                runner.Execute();
                Assert.AreEqual(0, count);
                runner.Execute();
                Assert.AreEqual(1, count);
                runner.Execute();
                Assert.AreEqual(1, count);
                runner.Execute();
                Assert.AreEqual(2, count);
                t.AssertCompletedSuccessfully();
            }

            async Task TestAsync()
            {
                count += await SubTestAsync();

                count += await SubTestAsync();
            }

            async Task <int> SubTestAsync()
            {
                await Task.Yield();

                await Task.Yield();

                return(1);
            }
        }
        public void FinishedTasksAreRemovedFromRunner()
        {
            var exHandler = new MockExceptionHandler();

            using (var runner = new LocalTaskRunner(exHandler))
            {
                runner.AssertRunningTaskCount(0);
                runner.StartTask(TestOfTAsync);
                runner.AssertRunningTaskCount(1);
                runner.Execute();
                runner.AssertRunningTaskCount(0);

                runner.AssertRunningTaskCount(0);
                runner.StartTask(TestAsync);
                runner.AssertRunningTaskCount(1);
                runner.Execute();
                runner.AssertRunningTaskCount(0);
            }

            async Task TestAsync()
            {
                await Task.Yield();
            }

            async Task <int> TestOfTAsync()
            {
                await Task.Yield();

                return(42);
            }
        }
        public void StartTaskThreadingStressTest()
        {
            var exHandler = new MockExceptionHandler();

            using (var runner = new LocalTaskRunner(exHandler))
            {
                // Start many tasks tasks in parallel.
                for (int i = 0; i < 100; i++)
                {
                    ThreadPool.QueueUserWorkItem(r => ((LocalTaskRunner)r).StartTask(TestAsync), runner);
                }

                // Wait for tasks to start.
                Thread.Sleep(millisecondsTimeout: 1000);

                // Execute a single tick to finish all tasks.
                runner.Execute();

                // Assert that all tasks have finished.
                runner.AssertRunningTaskCount(0);
            }

            async Task TestAsync()
            {
                await Task.Yield();
            }
        }
Beispiel #4
0
        public void YieldWaitsForNextExecute()
        {
            const int iterations = 25;

            var count = 0;

            using (var runner = new LocalTaskRunner(this.exceptionHandler))
            {
                runner.StartTask(WaitAndIncrementAsync);
                for (int i = 0; i < iterations; i++)
                {
                    Assert.AreEqual(i, count);
                    runner.Execute();
                }
            }

            async Task WaitAndIncrementAsync()
            {
                for (int i = 0; i < iterations; i++)
                {
                    await Task.Yield();

                    count++;
                }
            }
        }
        public void CallbackPostThreadingStressTest()
        {
            var exHandler = new MockExceptionHandler();

            using (var runner = new LocalTaskRunner(exHandler))
            {
                // Start the stress tasks.
                for (int i = 0; i < 50; i++)
                {
                    runner.StartTask(StressAsync);
                }

                // Execute enough times to finish all tasks.
                for (int i = 0; i < 99; i++)
                {
                    runner.Execute();
                    Thread.Sleep(10);
                }

                // Assert that all tasks have finished.
                runner.AssertRunningTaskCount(0);
            }

            async Task StressAsync()
            {
                /* This stresses the sync-context by posting callbacks from many different threads. */
                for (int i = 0; i < 50; i++)
                {
                    await Task.Run(() => Thread.Yield());
                }
            }
        }
Beispiel #6
0
        public void AwaitingSynchronousDependencyExecutesSynchronously()
        {
            using (var runner = new LocalTaskRunner(this.exceptionHandler))
            {
                var t = runner.StartTask(TestAsync, runner);
                t.AssertCompletedSuccessfully();
                Assert.AreEqual(2, t.Result);
            }

            async Task <int> TestAsync(ITaskRunner runner)
            {
                if (await runner.StartTask(DependencyAsync))
                {
                    return(1);
                }
                return(2);
            }

            async Task <bool> DependencyAsync()
            {
                if (DateTime.UtcNow.Year > 0)
                {
                    return(false);
                }

                await Task.Delay(TimeSpan.FromHours(1));

                return(true);
            }
        }
Beispiel #7
0
        public void CancelledExceptionIsReportedWhenAwaitingDisposedRunner()
        {
            using (var runner1 = new LocalTaskRunner(this.exceptionHandler))
            {
                using (var runner2 = new LocalTaskRunner(this.exceptionHandler))
                {
                    runner1.StartTask(TestAsync, runner2);
                    this.exceptionHandler.AssertNoExceptions();
                }

                runner1.Execute();
                this.exceptionHandler.AssertPop <TaskCanceledException>();
            }

            async Task TestAsync(ITaskRunner r)
            {
                await r.StartTask(GetIntAsync);
            }

            async Task <int> GetIntAsync()
            {
                await Task.Yield();

                return(42);
            }
        }
Beispiel #8
0
        public void CancelledTaskExceptionCanBeCaught()
        {
            using (var runner1 = new LocalTaskRunner(this.exceptionHandler))
            {
                Task <int> t;
                using (var runner2 = new LocalTaskRunner(this.exceptionHandler))
                    t = runner1.StartTask(TestAsync, runner2);

                runner1.Execute();
                Assert.AreEqual(-1, t.Result);
            }

            async Task <int> TestAsync(ITaskRunner r)
            {
                try
                {
                    return(await r.StartTask(GetIntAsync));
                }
                catch (TaskCanceledException)
                {
                    return(-1);
                }
            }

            async Task <int> GetIntAsync()
            {
                await Task.Yield();

                return(42);
            }
        }
        public void ExecuteThreadingStressTest()
        {
            var exHandler = new MockExceptionHandler();

            using (var runner = new LocalTaskRunner(exHandler))
            {
                // Start many tasks tasks.
                for (int i = 0; i < 100; i++)
                {
                    runner.StartTask(TestAsync);
                }

                for (int interation = 0; interation < 11; interation++)
                {
                    // Execute from many different threads in parallel.
                    for (int thread = 0; thread < 100; thread++)
                    {
                        ThreadPool.QueueUserWorkItem(r => ((LocalTaskRunner)r).Execute(), runner);
                    }

                    Thread.Sleep(millisecondsTimeout: 100);
                }

                // Assert that all tasks have finished.
                runner.AssertRunningTaskCount(0);
            }

            async Task TestAsync()
            {
                for (int i = 0; i < 10; i++)
                {
                    await Task.Yield();
                }
            }
        }
        public void CanBeDisposedMultipleTimes()
        {
            var exHandler = new MockExceptionHandler();
            var runner    = new LocalTaskRunner(exHandler);

            runner.Dispose();
            runner.Dispose();
        }
        public void DoesNotAllowExecuteAfterDispose()
        {
            var exHandler = new MockExceptionHandler();
            var runner    = new LocalTaskRunner(exHandler);

            runner.Dispose();

            Assert.Throws <ObjectDisposedException>(() => runner.Execute());
        }
        public void DoesNotAllowStartingTaskAfterDispose()
        {
            var exHandler = new MockExceptionHandler();
            var runner    = new LocalTaskRunner(exHandler);

            runner.Dispose();

            Assert.Throws <ObjectDisposedException>(() => runner.StartTask(() => Task.CompletedTask));
            Assert.Throws <ObjectDisposedException>(() => runner.StartTask(() => Task.FromResult <int>(42)));
        }
Beispiel #13
0
        public void ExceptionsInSynchronousMethodAreThrownDirectly()
        {
            using (var runner = new LocalTaskRunner(this.exceptionHandler))
            {
                Assert.Throws <TestException>(() => runner.StartTask(TestAsync));
            }

            Task TestAsync()
            {
                throw new TestException();
            }
        }
        public void ThrowsForTaskCreatorsThatReturnsNull()
        {
            var exHandler = new MockExceptionHandler();

            using (var runner = new LocalTaskRunner(exHandler))
            {
                Assert.Throws <TaskCreatorReturnedNullException>(() => runner.StartTask(TaskReturnNull));
                Assert.Throws <TaskCreatorReturnedNullException>(() => runner.StartTask(TaskOfTReturnNull));
            }

            Task TaskReturnNull() => null;
            Task <int> TaskOfTReturnNull() => null;
        }
        public void ThrowWhenTaskChangesSyncronizationContextInSyncronousPart()
        {
            var exHandler = new MockExceptionHandler();

            using (var runner = new LocalTaskRunner(exHandler))
            {
                Assert.Throws <ContextChangedException>(() => runner.StartTask(TaskThatChangesSyncContext));
            }

            Task TaskThatChangesSyncContext()
            {
                SynchronizationContext.SetSynchronizationContext(new MockSynchronizationContext());
                return(Task.CompletedTask);
            }
        }
Beispiel #16
0
        public void CancelTokenIsTrippedWhenDisposingRunning()
        {
            var heavyCalcRunning = false;

            using (var runner = new LocalTaskRunner(this.exceptionHandler))
            {
                runner.StartTask(TestAsync);

                // Wait for 'heavyCalc' to start on a different thread.
                while (!Volatile.Read(ref heavyCalcRunning))
                {
                    Thread.Yield();
                }
            }

            // Assert that 'HeavyCalc' stops.
            for (int i = 0; i < 100_000; i++)
            {
                if (!Volatile.Read(ref heavyCalcRunning))
                {
                    return;
                }
                Thread.Yield();
            }

            Assert.Fail("'HeavyCalcAsync' did not stop");

            async Task TestAsync(CancellationToken cancelToken)
            {
                await Task.Run(() => HeavyCalcAsync(cancelToken));
            }

            async Task <int> HeavyCalcAsync(CancellationToken cancelToken)
            {
                heavyCalcRunning = true;
                try
                {
                    await Task.Delay(TimeSpan.FromHours(1), cancelToken);

                    return(1);
                }
                catch (OperationCanceledException)
                {
                    heavyCalcRunning = false;
                    return(-1);
                }
            }
        }
Beispiel #17
0
        public void CodeBeforeAwaitRunsSynchronously()
        {
            var i = 0;

            using (var runner = new LocalTaskRunner(this.exceptionHandler))
            {
                runner.StartTask(IncrementAndWaitAsync);
                Assert.AreEqual(1, i);
            }

            async Task IncrementAndWaitAsync()
            {
                i++;
                await Task.Yield();
            }
        }
Beispiel #18
0
        public void ExceptionsAreReportedInSynchronousPartOfAsyncMethod()
        {
            using (var runner = new LocalTaskRunner(this.exceptionHandler))
            {
                runner.StartTask(TestAsync);
                this.exceptionHandler.AssertPop <TestException>();
            }

#pragma warning disable CS1998
            async Task TestAsync()
            {
                throw new TestException();
            }

#pragma warning restore CS1998
        }
        public void ResetsPreviousSynchronizationContextAfterExecute()
        {
            // Set custom sync-context.
            var syncContext = new MockSynchronizationContext();

            SynchronizationContext.SetSynchronizationContext(syncContext);

            var exHandler = new MockExceptionHandler();

            using (var runner = new LocalTaskRunner(exHandler))
            {
                runner.Execute();
            }

            // Verify that its again active.
            Assert.True(SynchronizationContext.Current == syncContext);
        }
Beispiel #20
0
        public void ExceptionsAreReportedInAsyncMethod()
        {
            using (var runner = new LocalTaskRunner(this.exceptionHandler))
            {
                runner.StartTask(TestAsync);
                this.exceptionHandler.AssertNoExceptions();
                runner.Execute();
                this.exceptionHandler.AssertPop <TestException>();
            }

            async Task TestAsync()
            {
                await Task.Yield();

                throw new TestException();
            }
        }
        public void ResetsPreviousSynchronizationContextWhenTaskCreatorThrows()
        {
            // Set custom sync-context.
            var syncContext = new MockSynchronizationContext();

            SynchronizationContext.SetSynchronizationContext(syncContext);

            var exHandler = new MockExceptionHandler();

            using (var runner = new LocalTaskRunner(exHandler))
            {
                Assert.Throws <TestException>(() => runner.StartTask(() => throw new TestException()));
            }

            // Verify that its again active.
            Assert.True(SynchronizationContext.Current == syncContext);
        }
Beispiel #22
0
        public void AwaitingCompletedTaskExecutesSynchronously()
        {
            var count = 0;

            using (var runner = new LocalTaskRunner(this.exceptionHandler))
            {
                runner.StartTask(TestAsync);
                Assert.AreEqual(1, count);
            }

            async Task TestAsync()
            {
                await Task.CompletedTask;
                await Task.CompletedTask;

                count++;
            }
        }
        public void StartingCompletedTaskIsReturnedDirectly()
        {
            var tcs = new TaskCompletionSource <int>();

            tcs.SetResult(42);
            Task <int> completedTaskOfInt = tcs.Task;
            Task       completedTask      = tcs.Task;

            var exHandler = new MockExceptionHandler();

            using (var runner = new LocalTaskRunner(exHandler))
            {
                var taskOfInt = runner.StartTask(taskCreator: () => completedTaskOfInt);
                Assert.True(object.ReferenceEquals(completedTaskOfInt, taskOfInt));

                var task = runner.StartTask(taskCreator: () => completedTask);
                Assert.True(object.ReferenceEquals(completedTask, task));
            }
        }
Beispiel #24
0
        public void TaskGetsCancelledWhenRunnerIsDisposed()
        {
            Task t;

            using (var runner = new LocalTaskRunner(this.exceptionHandler))
            {
                t = runner.StartTask(TestAsync);
                t.AssertRunning();
            }
            t.AssertCanceled();

            async Task TestAsync()
            {
                while (true)
                {
                    await Task.Yield();
                }
            }
        }
        public void StartingFaultedTaskIsReturnedDirectlyAndErrorIsReported()
        {
            var tcs = new TaskCompletionSource <int>();

            tcs.SetException(new TestException());
            Task <int> faultedTaskOfInt = tcs.Task;
            Task       faultedTask      = tcs.Task;

            var exHandler = new MockExceptionHandler();

            using (var runner = new LocalTaskRunner(exHandler))
            {
                var taskOfInt = runner.StartTask(taskCreator: () => faultedTaskOfInt);
                Assert.True(object.ReferenceEquals(faultedTaskOfInt, taskOfInt));
                exHandler.AssertPop <TestException>();

                var task = runner.StartTask(taskCreator: () => faultedTask);
                Assert.True(object.ReferenceEquals(faultedTask, task));
                exHandler.AssertPop <TestException>();
            }
        }
Beispiel #26
0
        public void TaskIsResumedWhenDependencyIsDone()
        {
            var count = 0;

            using (var runner = new LocalTaskRunner(this.exceptionHandler))
                using (var dependencyRunner = new LocalTaskRunner(this.exceptionHandler))
                {
                    var dep = dependencyRunner.StartTask(DependencyAsync);
                    var t   = runner.StartTask(TestAsync, dep);

                    // Task does not complete on its own.
                    runner.Execute();
                    Assert.AreEqual(0, count);

                    // But when completing dependency.
                    dependencyRunner.Execute();
                    Assert.AreEqual(0, count);

                    // And then executing the original running the task is completed.
                    runner.Execute();
                    t.AssertCompletedSuccessfully();
                    Assert.AreEqual(1, count);
                }

            async Task TestAsync(Task dependency)
            {
                await dependency;

                count++;
            }

            async Task DependencyAsync()
            {
                await Task.Yield();
            }
        }
Beispiel #27
0
 public MonoBehaviourTaskRunner()
 {
     this.taskRunner = new LocalTaskRunner(exceptionHandler: this);
 }
Beispiel #28
0
 void Start()
 {
     this.runner = new LocalTaskRunner(exceptionHandler: this);
     this.runner.StartTask(this.RunAsync);
 }
Beispiel #29
0
 void Start()
 {
     this.guiTaskRunner = new LocalTaskRunner(exceptionHandler: this);
     this.guiTaskRunner.StartTask(this.DrawUIAsync);
 }