public void Sched_SimpleFifoTest() { // This is not a great test because there's a 50/50 shot that it will work even if the scheduling // is completely and thoroughly broken and both closures are executed "simultaneously" UnitTestSchedulingContext context = new UnitTestSchedulingContext(); OrleansTaskScheduler orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context); ActivationTaskScheduler scheduler = orleansTaskScheduler.GetWorkItemGroup(context).TaskRunner; int n = 0; // ReSharper disable AccessToModifiedClosure IWorkItem item1 = new ClosureWorkItem(() => { n = n + 5; }); IWorkItem item2 = new ClosureWorkItem(() => { n = n * 3; }); // ReSharper restore AccessToModifiedClosure orleansTaskScheduler.QueueWorkItem(item1, context); orleansTaskScheduler.QueueWorkItem(item2, context); // Pause to let things run Thread.Sleep(1000); // N should be 15, because the two tasks should execute in order Assert.IsTrue(n != 0, "Work items did not get executed"); Assert.AreEqual(15, n, "Work items executed out of order"); Console.WriteLine("Test executed OK."); orleansTaskScheduler.Stop(); }
public async Task Sched_Task_SubTaskExecutionSequencing() { UnitTestSchedulingContext context = new UnitTestSchedulingContext(); this.scheduler.RegisterWorkContext(context); LogContext("Main-task " + Task.CurrentId); int n = 0; TaskCompletionSource <int> finished = new TaskCompletionSource <int>(); var numCompleted = new[] { 0 }; Action closure = () => { LogContext("ClosureWorkItem-task " + Task.CurrentId); for (int i = 0; i < 10; i++) { int id = -1; Action action = () => { id = Task.CurrentId.HasValue ? (int)Task.CurrentId : -1; // ReSharper disable AccessToModifiedClosure LogContext("Sub-task " + id + " n=" + n); int k = n; this.output.WriteLine("Sub-task " + id + " sleeping"); Thread.Sleep(100); this.output.WriteLine("Sub-task " + id + " awake"); n = k + 1; // ReSharper restore AccessToModifiedClosure }; Task.Factory.StartNew(action).ContinueWith(tsk => { LogContext("Sub-task " + id + "-ContinueWith"); this.output.WriteLine("Sub-task " + id + " Done"); if (Interlocked.Increment(ref numCompleted[0]) == 10) { finished.SetResult(0); } }); } }; IWorkItem workItem = new ClosureWorkItem(closure); this.scheduler.QueueWorkItem(workItem, context); // Pause to let things run this.output.WriteLine("Main-task sleeping"); await Task.WhenAny(Task.Delay(TimeSpan.FromSeconds(10)), finished.Task); this.output.WriteLine("Main-task awake"); // N should be 10, because all tasks should execute serially Assert.True(n != 0, "Work items did not get executed"); Assert.Equal(10, n); // "Work items executed concurrently" this.scheduler.Stop(); }
public void Sched_Task_SubTaskExecutionSequencing() { UnitTestSchedulingContext rootContext = new UnitTestSchedulingContext(); OrleansTaskScheduler scheduler = TestInternalHelper.InitializeSchedulerForTesting(rootContext); UnitTestSchedulingContext context = new UnitTestSchedulingContext(); scheduler.RegisterWorkContext(context); LogContext("Main-task " + Task.CurrentId); int n = 0; Action closure = () => { LogContext("ClosureWorkItem-task " + Task.CurrentId); for (int i = 0; i < 10; i++) { int id = -1; Action action = () => { id = Task.CurrentId.HasValue ? (int)Task.CurrentId : -1; // ReSharper disable AccessToModifiedClosure LogContext("Sub-task " + id + " n=" + n); int k = n; Console.WriteLine("Sub-task " + id + " sleeping"); Thread.Sleep(100); Console.WriteLine("Sub-task " + id + " awake"); n = k + 1; // ReSharper restore AccessToModifiedClosure }; Task.Factory.StartNew(action).ContinueWith(tsk => { LogContext("Sub-task " + id + "-ContinueWith"); Console.WriteLine("Sub-task " + id + " Done"); }); } }; IWorkItem workItem = new ClosureWorkItem(closure); scheduler.QueueWorkItem(workItem, context); // Pause to let things run Console.WriteLine("Main-task sleeping"); Thread.Sleep(TimeSpan.FromSeconds(2)); Console.WriteLine("Main-task awake"); // N should be 10, because all tasks should execute serially Assert.IsTrue(n != 0, "Work items did not get executed"); Assert.AreEqual(10, n, "Work items executed concurrently"); scheduler.Stop(); }
public void Sched_Task_ClosureWorkItem_Wait() { UnitTestSchedulingContext cntx = new UnitTestSchedulingContext(); OrleansTaskScheduler scheduler = TestInternalHelper.InitializeSchedulerForTesting(cntx); const int NumTasks = 10; ManualResetEvent[] flags = new ManualResetEvent[NumTasks]; for (int i = 0; i < NumTasks; i++) { flags[i] = new ManualResetEvent(false); } Task[] tasks = new Task[NumTasks]; for (int i = 0; i < NumTasks; i++) { int taskNum = i; // Capture tasks[i] = new Task(() => { Console.WriteLine("Inside Task-" + taskNum); flags[taskNum].WaitOne(); }); } ClosureWorkItem[] workItems = new ClosureWorkItem[NumTasks]; for (int i = 0; i < NumTasks; i++) { int taskNum = i; // Capture workItems[i] = new ClosureWorkItem(() => { Console.WriteLine("Inside ClosureWorkItem-" + taskNum); tasks[taskNum].Start(scheduler); bool ok = tasks[taskNum].Wait(TimeSpan.FromMilliseconds(NumTasks * 100)); Assert.IsTrue(ok, "Wait completed successfully inside ClosureWorkItem-" + taskNum); }); } foreach (var workItem in workItems) { scheduler.QueueWorkItem(workItem, cntx); } foreach (var flag in flags) { flag.Set(); } for (int i = 0; i < tasks.Length; i++) { bool ok = tasks[i].Wait(TimeSpan.FromMilliseconds(NumTasks * 150)); Assert.IsTrue(ok, "Wait completed successfully for Task-" + i); } for (int i = 0; i < tasks.Length; i++) { Assert.IsFalse(tasks[i].IsFaulted, "Task.IsFaulted-" + i + " Exception=" + tasks[i].Exception); Assert.IsTrue(tasks[i].IsCompleted, "Task.IsCompleted-" + i); } }
public void Sched_Task_ClosureWorkItem_Wait() { const int NumTasks = 10; ManualResetEvent[] flags = new ManualResetEvent[NumTasks]; for (int i = 0; i < NumTasks; i++) { flags[i] = new ManualResetEvent(false); } Task[] tasks = new Task[NumTasks]; for (int i = 0; i < NumTasks; i++) { int taskNum = i; // Capture tasks[i] = new Task(() => { this.output.WriteLine("Inside Task-" + taskNum); flags[taskNum].WaitOne(); }); } ClosureWorkItem[] workItems = new ClosureWorkItem[NumTasks]; for (int i = 0; i < NumTasks; i++) { int taskNum = i; // Capture workItems[i] = new ClosureWorkItem(() => { this.output.WriteLine("Inside ClosureWorkItem-" + taskNum); tasks[taskNum].Start(this.scheduler); bool ok = tasks[taskNum].Wait(TimeSpan.FromMilliseconds(NumTasks * 100)); Assert.True(ok, "Wait completed successfully inside ClosureWorkItem-" + taskNum); }); } foreach (var workItem in workItems) { this.scheduler.QueueWorkItem(workItem, this.rootContext); } foreach (var flag in flags) { flag.Set(); } for (int i = 0; i < tasks.Length; i++) { bool ok = tasks[i].Wait(TimeSpan.FromMilliseconds(NumTasks * 150)); Assert.True(ok, "Wait completed successfully for Task-" + i); } for (int i = 0; i < tasks.Length; i++) { Assert.False(tasks[i].IsFaulted, "Task.IsFaulted-" + i + " Exception=" + tasks[i].Exception); Assert.True(tasks[i].IsCompleted, "Task.IsCompleted-" + i); } }
public void Sched_SimpleFifoTest() { // This is not a great test because there's a 50/50 shot that it will work even if the scheduling // is completely and thoroughly broken and both closures are executed "simultaneously" ActivationTaskScheduler activationScheduler = this.scheduler.GetWorkItemGroup(this.rootContext).TaskRunner; int n = 0; // ReSharper disable AccessToModifiedClosure IWorkItem item1 = new ClosureWorkItem(() => { n = n + 5; }); IWorkItem item2 = new ClosureWorkItem(() => { n = n * 3; }); // ReSharper restore AccessToModifiedClosure this.scheduler.QueueWorkItem(item1, this.rootContext); this.scheduler.QueueWorkItem(item2, this.rootContext); // Pause to let things run Thread.Sleep(1000); // N should be 15, because the two tasks should execute in order Assert.True(n != 0, "Work items did not get executed"); Assert.Equal(15, n); this.output.WriteLine("Test executed OK."); }