public void ExceptionTestAsyncAll() { var scheduler = new GateScheduler(NumThreads); for (var r = 0; r < Reps; ++r) { int N = 100; var tasks = new Task <int> [100]; for (int i = 0; i < N; ++i) { var index = i; var prio = i % 3; var thread = i % NumThreads; tasks[i] = scheduler.GatedRun(prio, async(gate) => { await gate.WaitToContinueAsync(); throw new MyException(); #pragma warning disable CS0162 // Unreachable code detected return(index); #pragma warning restore CS0162 // Unreachable code detected }); } // some tasks should throw for (var i = 0; i < N; ++i) { Assert.Throws <MyException>(() => tasks[i].GetAwaiter().GetResult()); } } }
public void TaskCancellationTestAsyncSome() { using var ctsScheduler = new CancellationTokenSource(); for (var r = 0; r < Reps; ++r) { using var ctsTask = new CancellationTokenSource(); ctsTask.Cancel(); var scheduler = new GateScheduler(NumThreads); 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.GatedRun(prio, async(gate) => { await gate.WaitToContinueAsync(); // 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. // NOTE: in the async case, we expect the task to be CANCELLED, not FAULTED, even though // the exception was thrown from the task itself; this contradicts the non-async task // case. This matches the behaviour of Task.Run(async () xxx) Assert.Throws <OperationCanceledException>(() => tasks[i].GetAwaiter().GetResult()); Assert.True(tasks[i].IsCanceled); Assert.False(tasks[i].IsFaulted); } else { Assert.Equal(i, tasks[i].Result); } } ctsScheduler.Cancel(); } }
static async Task ExampleGateScheduler() { Console.WriteLine(); Console.WriteLine(); Console.WriteLine("GateScheduler..."); Console.WriteLine(); using var cts = new CancellationTokenSource(); const int Prios = 3; const int PerThread = 20; var gateScheduler = new GateScheduler(Environment.ProcessorCount); var tasks = new List <Task <double> >(); foreach (var p in Enumerable.Range(0, Prios).Reverse()) { // add them in slowly -- watch for tasks getting pre-empted by more important ones Thread.Sleep(250); Console.WriteLine($"-- Starting prio {p}"); foreach (var t in Enumerable.Range(0, Environment.ProcessorCount)) { var thread = t; var task = gateScheduler.GatedRun(p, async gate => { var priority = p;
public void PreCancellationTestAsync() { using var ctsScheduler = new CancellationTokenSource(); for (var r = 0; r < Reps; ++r) { using var ctsTask = new CancellationTokenSource(); ctsTask.Cancel(); var scheduler = new GateScheduler(NumThreads); 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.GatedRun(prio, async(gate) => { // should not be here if we should cancel prior Assert.False(shouldCancel, "throw inside the task; should never get here"); await gate.WaitToContinueAsync(); // 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(); } }
public void MutiplePriority_LowestPrioNumberCompletesFirst() { int PrioLevels = 5; int NumThreads = 4; int N = 50; var scheduler = new GateScheduler(NumThreads); // 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 ExceptionTestAsyncSome() { var scheduler = new GateScheduler(NumThreads); for (var r = 0; r < Reps; ++r) { 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.GatedRun(prio, async(gate) => { await gate.WaitToContinueAsync(); 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); } } } }
public SchedulerPerf() { _cancellationTokenSource = new CancellationTokenSource(); _orderingScheduler = new OrderingScheduler(Environment.ProcessorCount, _cancellationTokenSource.Token); _gateScheduler = new GateScheduler(Environment.ProcessorCount); }