public void DoesNotLoseAnyTaskWithTwoWriterThreadsOnTheSameSequencer() { var rootDispatcher = new DotNetThreadPoolUnitOfExecution(); var sequencer = new Sequencer(rootDispatcher); const int NumberOfWritesPerThread = 10000; var tasksOutput = new List <int>(); using (var unleashThreadsEvent = new AutoResetEvent(false)) using (var firstWriterFinishedEvent = new AutoResetEvent(false)) using (var secondWriterFinishedEvent = new AutoResetEvent(false)) { var firstWriter = new Thread(() => this.WriterRoutine(sequencer, unleashThreadsEvent, 0, NumberOfWritesPerThread, tasksOutput, firstWriterFinishedEvent)); firstWriter.Start(); var secondWriter = new Thread(() => this.WriterRoutine(sequencer, unleashThreadsEvent, 0, NumberOfWritesPerThread, tasksOutput, secondWriterFinishedEvent)); secondWriter.Start(); // ready, set, mark unleashThreadsEvent.Set(); // Waits until the two writers have finished their writes Check.That(firstWriterFinishedEvent.WaitOne(2 * ThreeSecondsMax) && secondWriterFinishedEvent.WaitOne(2 * ThreeSecondsMax)).IsTrue(); // Checks that no write has been missing Check.That(tasksOutput).HasSize(2 * NumberOfWritesPerThread); } }
public void SequencerExecutesTasksInTheOrderOfTheirDispatch() { var rootDispatcher = new DotNetThreadPoolUnitOfExecution(); var sequencer = new Sequencer(rootDispatcher); const int TasksNumber = 100000; var tasksOutput = new List <int>(); using (var dispatchingFinishedEvent = new AutoResetEvent(false)) { // Dispatches tasks to the sequencer for (int i = 0; i < TasksNumber; i++) { int antiClosureSideEffectNumber = i; sequencer.Dispatch(() => tasksOutput.Add(antiClosureSideEffectNumber)); } // Indicates the end of the sequence with a final task sequencer.Dispatch(() => dispatchingFinishedEvent.Set()); // Waits for sequence completion Check.That(dispatchingFinishedEvent.WaitOne(ThreeSecondsMax)).IsTrue(); // Checks that everything was properly processed in sequence for (int k = 0; k < TasksNumber; k++) { Check.That(tasksOutput[k]).IsEqualTo(k); } } }
public void Should_Execute_Tasks_Sequentially() { var poolExec = new DotNetThreadPoolUnitOfExecution(); ISequencer sequencer = this.BuildSequencer(poolExec); var context = new RaceConditionDetector(); sequencer.Dispatch(() => context.Delay(20)); int current = 0; bool failed = false; for (int i = 0; i < 1000; i++) { int targetCount = i; sequencer.Dispatch( () => { // we check if the task is executed at the proper rank if (targetCount != current) { failed = true; } current++; }); } Check.That(context.WaitForTasks(1)).IsFalse(); Check.That(failed).IsFalse(); }
public void DoesNotLoseAnyTaskWithTwoWriterThreadsOnTheSameSequencer() { var rootDispatcher = new DotNetThreadPoolUnitOfExecution(); var sequencer = new Sequencer(rootDispatcher); const int NumberOfWritesPerThread = 10000; var tasksOutput = new List<int>(); using (var unleashThreadsEvent = new AutoResetEvent(false)) using (var firstWriterFinishedEvent = new AutoResetEvent(false)) using (var secondWriterFinishedEvent = new AutoResetEvent(false)) { var firstWriter = new Thread(() => this.WriterRoutine(sequencer, unleashThreadsEvent, 0, NumberOfWritesPerThread, tasksOutput, firstWriterFinishedEvent)); firstWriter.Start(); var secondWriter = new Thread(() => this.WriterRoutine(sequencer, unleashThreadsEvent, 0, NumberOfWritesPerThread, tasksOutput, secondWriterFinishedEvent)); secondWriter.Start(); // ready, set, mark unleashThreadsEvent.Set(); // Waits until the two writers have finished their writes Check.That(firstWriterFinishedEvent.WaitOne(2 * ThreeSecondsMax) && secondWriterFinishedEvent.WaitOne(2 * ThreeSecondsMax)).IsTrue(); // Checks that no write has been missing Check.That(tasksOutput).HasSize(2 * NumberOfWritesPerThread); } }
public void SequencerExecutesTasksInTheOrderOfTheirDispatch() { var rootDispatcher = new DotNetThreadPoolUnitOfExecution(); var sequencer = new Sequencer(rootDispatcher); const int TasksNumber = 100000; var tasksOutput = new List<int>(); using (var dispatchingFinishedEvent = new AutoResetEvent(false)) { // Dispatches tasks to the sequencer for (int i = 0; i < TasksNumber; i++) { int antiClosureSideEffectNumber = i; sequencer.Dispatch(() => tasksOutput.Add(antiClosureSideEffectNumber)); } // Indicates the end of the sequence with a final task sequencer.Dispatch(() => dispatchingFinishedEvent.Set()); // Waits for sequence completion Check.That(dispatchingFinishedEvent.WaitOne(ThreeSecondsMax)).IsTrue(); // Checks that everything was properly processed in sequence for (int k = 0; k < TasksNumber; k++) { Check.That(tasksOutput[k]).IsEqualTo(k); } } }
public void Should_Execute_Tasks_Non_Concurrently() { var poolExec = new DotNetThreadPoolUnitOfExecution(); ISequencer sequencer = this.BuildSequencer(poolExec); var context = new RaceConditionDetector(); // first task inject delay sequencer.Dispatch(() => context.Delay(20)); // second task check non concurrence sequencer.Dispatch(() => context.Delay(20)); // wait for the two tasks to be executed context.WaitForTasks(2); Check.That(context.RaceConditionDetected).IsFalse(); }