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) =>
         {
         });
 }