public static void TestAddingSubscribersToWorkerThread() { using (WorkerGroup workerGroup = new WorkerGroup()) { IThreadWorker worker = workerGroup.CreateWorker(); bool wasPrepared = false; worker.Prepare += (object sender, ThreadWorkerEventArgs e) => { wasPrepared = true; }; bool didWork = false; worker.Work += (object sender, ThreadWorkerEventArgs e) => { didWork = true; }; bool didComplete = false; worker.Completing += (object sender, ThreadWorkerEventArgs e) => { didComplete = true; }; worker.Run(); workerGroup.WaitAllAndFinish(); Assert.That(wasPrepared, "The Prepare event should be raised."); Assert.That(didWork, "The Work event should be raised."); Assert.That(didComplete, "The Completed event should be raised."); } }
public static void TestCoreFunctionality() { int threadCount = 0; int maxCount = 0; using (WorkerGroup workerGroup = new WorkerGroup()) { object threadLock = new object(); IThreadWorker worker1 = workerGroup.CreateWorker(); worker1.Work += (object sender, ThreadWorkerEventArgs e) => { lock (threadLock) { ++threadCount; if (threadCount > maxCount) { maxCount = threadCount; } } Thread.Sleep(100); }; worker1.Completing += (object sender, ThreadWorkerEventArgs e) => { --threadCount; }; worker1.Run(); IThreadWorker worker2 = workerGroup.CreateWorker(); worker2.Work += (object sender, ThreadWorkerEventArgs e) => { lock (threadLock) { ++threadCount; if (threadCount > maxCount) { maxCount = threadCount; } } Thread.Sleep(100); }; worker2.Completing += (object sender, ThreadWorkerEventArgs e) => { --threadCount; }; worker2.Run(); workerGroup.WaitAllAndFinish(); Assert.That(maxCount, Is.EqualTo(1), "There should never be more than one thread active at one time."); } }
public static void TestProgressing() { using (WorkerGroup workerGroup = new WorkerGroup()) { int percent = 0; workerGroup.Progress.Progressing += (object sender, ProgressEventArgs e) => { percent = e.Percent; }; IThreadWorker worker = workerGroup.CreateWorker(); worker.Run(); workerGroup.WaitAllAndFinish(); Assert.That(percent, Is.EqualTo(100), "Progress at 100 percent should always be reported when the thread completes."); } }
public static void TestRemovingSubscribersFromWorkerThread() { using (WorkerGroup workerGroup = new WorkerGroup()) { IThreadWorker worker = workerGroup.CreateWorker(); worker.Prepare += ThreadWorkerEventHandler; worker.Work += ThreadWorkerEventHandler; worker.Completing += ThreadWorkerEventHandler; worker.Run(); workerGroup.WaitAllAndFinish(); Assert.That(workerGroup.FirstError, Is.EqualTo(FileOperationStatus.UnspecifiedError), "The status should be set by one of the event handlers."); } using (WorkerGroup workerGroup = new WorkerGroup()) { IThreadWorker worker = workerGroup.CreateWorker(); worker.Prepare += ThreadWorkerEventHandler; worker.Work += ThreadWorkerEventHandler; worker.Completing += ThreadWorkerEventHandler; worker.Prepare -= ThreadWorkerEventHandler; worker.Work -= ThreadWorkerEventHandler; worker.Completing -= ThreadWorkerEventHandler; worker.Run(); workerGroup.WaitAllAndFinish(); Assert.That(workerGroup.FirstError, Is.EqualTo(FileOperationStatus.Success), "None of the event handlers should have been called, so the status should not have been set there."); } }
public static void TestInvalidOperationException() { using (WorkerGroup workerGroup = new WorkerGroup()) { IThreadWorker worker = workerGroup.CreateWorker(); bool? f = null; Assert.Throws<InvalidOperationException>(() => { f = worker.HasCompleted; }); Assert.That(!f.HasValue, "No value should be set, since an exception should have occurred."); Assert.Throws<InvalidOperationException>(() => { worker.Join(); }); worker.Abort(); } }
public static void TestObjectDisposed() { WorkerGroup workerGroup = new WorkerGroup(); IThreadWorker worker = workerGroup.CreateWorker(); worker.Run(); workerGroup.Dispose(); worker = null; Assert.Throws<ObjectDisposedException>(() => { worker = workerGroup.CreateWorker(); }, "A call to a method on a disposed object should raise ObjectDisposedException."); Assert.That(worker, Is.Null, "The worker should still be null, since the previous attempt to create should fail with an exception."); Assert.Throws<ObjectDisposedException>(() => { workerGroup.WaitAllAndFinish(); }, "A call to a method on a disposed object should raise ObjectDisposedException."); }
public static void TestFinishInBackground() { bool didComplete = false; ProgressContext progress = new ProgressContext(); progress.Progressing += (object sender2, ProgressEventArgs e2) => { didComplete = true; }; using (ThreadWorker threadWorker = new ThreadWorker(progress)) { threadWorker.Work += (object sender, ThreadWorkerEventArgs e) => { using (WorkerGroup workerGroup = new WorkerGroup(progress)) { IThreadWorker worker = workerGroup.CreateWorker(); worker.Work += (object sender2, ThreadWorkerEventArgs e2) => { e2.Progress.NotifyLevelStart(); e2.Progress.NotifyLevelFinished(); }; worker.Run(); } }; threadWorker.Run(); } Assert.That(didComplete, "Execution should continue here, with the flag set indicating that the progress event occurred."); }
public static void TestExplicitConstructor() { ProgressContext progress = new ProgressContext(); int percent = 0; progress.Progressing += (object sender, ProgressEventArgs e) => { percent = e.Percent; }; using (WorkerGroup workerGroup = new WorkerGroup(1, progress)) { IThreadWorker worker = workerGroup.CreateWorker(); worker.Run(); workerGroup.WaitAllAndFinish(); } Assert.That(percent, Is.EqualTo(100), "Progress at 100 percent should always be reported when the thread completes."); }
public static void TestDoubleFinished() { using (WorkerGroup workerGroup = new WorkerGroup()) { IThreadWorker worker = workerGroup.CreateWorker(); worker.Run(); workerGroup.WaitAllAndFinish(); Assert.Throws<InvalidOperationException>(() => { workerGroup.WaitAllAndFinish(); }); } }
public static void TestDoubleDispose() { Assert.DoesNotThrow(() => { using (WorkerGroup workerGroup = new WorkerGroup()) { IThreadWorker worker = workerGroup.CreateWorker(); worker.Run(); workerGroup.Dispose(); } }); }
private void ProcessFilesInBackground(IEnumerable<string> files, Action<string, IThreadWorker, ProgressContext> processFile) { WorkerGroup workerGroup = null; int maxConcurrency = Environment.ProcessorCount > 2 ? Environment.ProcessorCount - 1 : 2; progressBackgroundWorker.BackgroundWorkWithProgress( (ProgressContext progress) => { progress.AddItems(files.Count()); using (workerGroup = new WorkerGroup(maxConcurrency, progress)) { foreach (string file in files) { IThreadWorker worker = workerGroup.CreateWorker(); string closureOverCopyOfLoopVariableFile = file; InteractionSafeUi(() => { processFile(closureOverCopyOfLoopVariableFile, worker, progress); }); if (workerGroup.FirstError != FileOperationStatus.Success) { break; } progress.AddItems(-1); } workerGroup.WaitAllAndFinish(); return workerGroup.FirstError; } }, (FileOperationStatus status) => { }); }