public void PreCancellationTest() { using var ctsScheduler = new CancellationTokenSource(); using var ctsTask = new CancellationTokenSource(); ctsTask.Cancel(); var scheduler = new OrderingScheduler(NumThreads, ctsScheduler.Token); int N = 100; var tasks = new Task <int> [100]; var shouldCancels = new bool[100]; for (int i = 0; i < N; ++i) { var index = i; var prio = i % 3; var thread = i % NumThreads; var shouldCancel = i % 5 == 0; var token = ctsTask.Token; shouldCancels[i] = shouldCancel; var cancellationToken = shouldCancel ? token : CancellationToken.None; tasks[i] = scheduler.Run(prio, thread, () => { // should not be here if we should cancel prior Assert.False(shouldCancel, "throw inside the task; should never get here"); // complete successfully return(index); }, // set cancellation token on the task -- this should cancel the task before it starts cancellationToken); } // some tasks should throw for (var i = 0; i < N; ++i) { if (shouldCancels[i]) { // task should be cancelled BEFORE running, meaning it's CANCELLED, not FAULTED Assert.Throws <TaskCanceledException>(() => tasks[i].GetAwaiter().GetResult()); Assert.True(tasks[i].IsCanceled); Assert.False(tasks[i].IsFaulted); } else { Assert.Equal(i, tasks[i].Result); } } ctsScheduler.Cancel(); scheduler.WaitForShutdown(); }
public void TaskCancellationTest() { using var ctsScheduler = new CancellationTokenSource(); using var ctsTask = new CancellationTokenSource(); ctsTask.Cancel(); var scheduler = new OrderingScheduler(NumThreads, ctsScheduler.Token); int N = 100; var tasks = new Task <int> [100]; var shouldCancels = new bool[100]; for (int i = 0; i < N; ++i) { var index = i; var prio = i % 3; var thread = i % NumThreads; var shouldCancel = i % 5 == 0; var token = ctsTask.Token; shouldCancels[i] = shouldCancel; tasks[i] = scheduler.Run(prio, thread, () => { // throw INSIDE task if (shouldCancel) { token.ThrowIfCancellationRequested(); } return(index); }); } // some tasks should throw for (var i = 0; i < N; ++i) { if (shouldCancels[i]) { // task should be cancelled WHILE running, meaning it's FAULTED, not CANCELLED Assert.Throws <OperationCanceledException>(() => tasks[i].GetAwaiter().GetResult()); Assert.False(tasks[i].IsCanceled); Assert.True(tasks[i].IsFaulted); } else { Assert.Equal(i, tasks[i].Result); } } ctsScheduler.Cancel(); scheduler.WaitForShutdown(); }
public void LowestPrioNumberCompletesFirst() { int PrioLevels = 5; int NumThreads = 4; int N = 1000; using var cts = new CancellationTokenSource(); var scheduler = new OrderingScheduler(NumThreads, cts.Token); // use this to synchronise start; we don't support asynchronous tasks, so we // just cause them to block. This is to improve test reliability -- ensure we // have everything queued before letting them proceed. var syncStart = new ManualResetEventSlim(false); // set up 3 sets of prioritised tasks; and queue the least important // (highest prio number) first to make life more difficult. Task <(int, int)>[][] tasks = new Task <(int, int)> [PrioLevels][];
public void ExceptionTest() { using var cts = new CancellationTokenSource(); var scheduler = new OrderingScheduler(NumThreads, cts.Token); int N = 100; var tasks = new Task <int> [100]; var shouldThrows = new bool[100]; for (int i = 0; i < N; ++i) { var index = i; var prio = i % 3; var thread = i % NumThreads; var shouldThrow = i % 5 == 0; shouldThrows[i] = shouldThrow; tasks[i] = scheduler.Run(prio, thread, () => { if (shouldThrow) { throw new MyException(); } return(index); }); } // some tasks should throw for (var i = 0; i < N; ++i) { if (shouldThrows[i]) { Assert.Throws <MyException>(() => tasks[i].GetAwaiter().GetResult()); } else { Assert.Equal(i, tasks[i].Result); } } cts.Cancel(); scheduler.WaitForShutdown(); }
public SchedulerPerf() { _cancellationTokenSource = new CancellationTokenSource(); _orderingScheduler = new OrderingScheduler(Environment.ProcessorCount, _cancellationTokenSource.Token); _gateScheduler = new GateScheduler(Environment.ProcessorCount); }