public void DoWorkShouldExitWorkerThreadWhenWorkerThreadManagerShouldExitWorkerThreadReturnsTrueAndWorkItemQueueIsEmpty() { WorkerThreadManagerStub workerThreadManager = WorkerThreadManagerStub.Create(); ManualResetEvent manualResetEvent = new ManualResetEvent(false); IWorkItemQueue workItemQueue = Substitute.For <IWorkItemQueue>(); workItemQueue.Dequeue().Returns((IWorkItem)null); bool exitedBecaseWorkItemQueueIsEmpty = false; WorkerThread workerThread = new WorkerThread(workerThreadManager, workItemQueue, "Test", false); workerThreadManager.WorkerThreadExiting += (sender, args) => { if (args.WorkerThreadExitReason == WorkerThreadExitReason.WorkItemQueueIsEmpty) { exitedBecaseWorkItemQueueIsEmpty = true; manualResetEvent.Set(); } }; workerThreadManager.ShouldExitWorkerThread(workerThread, false).Returns(false); workerThreadManager.ShouldExitWorkerThread(workerThread, true).Returns(true); workerThread.Start(); manualResetEvent.WaitOne(500); workerThread.Stop(); Wait.While(() => workerThread.Thread.IsAlive, 300); Assert.AreEqual(false, workerThread.Thread.IsAlive); workItemQueue.Received(1).Dequeue(); Assert.AreEqual(true, exitedBecaseWorkItemQueueIsEmpty); }
public void StopShouldCallCurrentWorkItemStopMethodWhenCalledDuringAnyWorkItemIsInProgress() { WorkerThreadManagerStub workerThreadManager = WorkerThreadManagerStub.Create(); ManualResetEvent startWaitHandle = new ManualResetEvent(false); ManualResetEvent stopWaitHandle = new ManualResetEvent(false); IWorkItemQueue workItemQueue = Substitute.For <IWorkItemQueue>(); IWorkItem workItem = Substitute.For <IWorkItem>(); workItem.When(x => x.DoWork()).Do( x => { startWaitHandle.Set(); stopWaitHandle.WaitOne(500); }); workItemQueue.Dequeue().Returns(workItem); WorkerThread workerThread = new WorkerThread(workerThreadManager, workItemQueue, "Test", false); workerThread.Start(); startWaitHandle.WaitOne(500); workerThread.Stop(); stopWaitHandle.Set(); Wait.While(() => workerThread.Thread.IsAlive, 500); Assert.AreEqual(false, workerThread.Thread.IsAlive); workItem.Received(1).Stop(); }
public void DoWorkShouldCallWorkerThreadWorkItemExceptionEventWhenWorkItemIsCompletedWithException() { WorkerThreadManagerStub workerThreadManager = WorkerThreadManagerStub.Create(); Exception invalidCastException = new InvalidCastException(); ManualResetEvent manualResetEvent = new ManualResetEvent(false); IWorkItemQueue workItemQueue = Substitute.For <IWorkItemQueue>(); IWorkItem workItem = Substitute.For <IWorkItem>(); workItem.When(x => x.DoWork()).Do( x => { throw invalidCastException; }); workItemQueue.Dequeue().Returns(workItem); Exception otherThreadsException = null; bool workerThreadWorkItemExceptionEventIsCalled = false; WorkerThread workerThread = new WorkerThread(workerThreadManager, workItemQueue, "Test", false); workerThreadManager.WorkerThreadWorkItemException += (sender, args) => { workerThreadWorkItemExceptionEventIsCalled = true; try { Assert.AreEqual(WorkItemState.CompletedWithException, workItem.State); Assert.AreEqual(workItem, args.WorkItem); Assert.AreEqual(workItem.LastException, args.Exception); Assert.AreEqual(invalidCastException, args.Exception); workItem.Received(1).DoWork(); } catch (Exception ex) { otherThreadsException = ex; } workerThread.Stop(); manualResetEvent.Set(); }; workerThread.Start(); manualResetEvent.WaitOne(500); workerThread.Stop(); Wait.While(() => workerThread.Thread.IsAlive, 300); Assert.AreEqual(false, workerThread.Thread.IsAlive); Assert.AreEqual(true, workerThreadWorkItemExceptionEventIsCalled); if (otherThreadsException != null) { throw otherThreadsException; } }
public void DoWorkShouldCallWorkerThreadExitingEventWhenThreadIsAborted() { WorkerThreadManagerStub workerThreadManager = WorkerThreadManagerStub.Create(); ManualResetEvent manualResetEvent = new ManualResetEvent(false); IWorkItemQueue workItemQueue = Substitute.For <IWorkItemQueue>(); IWorkItem workItem = Substitute.For <IWorkItem>(); workItemQueue.Dequeue().Returns(workItem); Exception otherThreadsException = null; bool workerThreadExitingEventIsCalled = false; WorkerThread workerThread = new WorkerThread(workerThreadManager, workItemQueue, "Test", false); workerThreadManager.WorkerThreadExiting += (sender, args) => { workerThreadExitingEventIsCalled = true; try { Assert.AreEqual(WorkerThreadExitReason.ThreadAborted, args.WorkerThreadExitReason); } catch (Exception ex) { otherThreadsException = ex; } manualResetEvent.Set(); }; workerThread.Start(); Wait.While(() => !workerThread.Thread.IsAlive, 300); workerThread.Thread.Abort(); manualResetEvent.WaitOne(500); workerThread.Stop(); Wait.While(() => workerThread.Thread.IsAlive, 300); Assert.AreEqual(false, workerThread.Thread.IsAlive); Assert.AreEqual(true, workerThreadExitingEventIsCalled); if (otherThreadsException != null) { throw otherThreadsException; } }
public void ConstructorShoulStartMinimumCountWorkerThreadsAlthoughThereIsNoWorkItemsInTheQueue() { IWorkItemQueue workItemQueue = Substitute.For <IWorkItemQueue>(); workItemQueue.Count.Returns(0); workItemQueue.Dequeue().Returns((IWorkItem)null); WorkerThreadPool workerThreadPool = new WorkerThreadPool(workItemQueue, 2, 2); Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount); Wait.While(() => !workerThreadPool.WorkerThreads.All(x => x.Thread.IsAlive), 500); Assert.AreEqual(0, workerThreadPool.WorkerThreads.Count(x => x.IsBusy)); workerThreadPool.Shutdown(true, 500); }
public void DoWorkShouldCallWorkerThreadWorkItemStartingBeforeProcessingWorkItem() { WorkerThreadManagerStub workerThreadManager = WorkerThreadManagerStub.Create(); ManualResetEvent manualResetEvent = new ManualResetEvent(false); IWorkItemQueue workItemQueue = Substitute.For <IWorkItemQueue>(); IWorkItem workItem = Substitute.For <IWorkItem>(); workItemQueue.Dequeue().Returns(workItem); Exception otherThreadsException = null; WorkerThread workerThread = new WorkerThread(workerThreadManager, workItemQueue, "Test", false); workerThreadManager.WorkerThreadWorkItemStarting += (sender, args) => { try { Assert.AreEqual(workItem, args.WorkItem); workItem.DidNotReceive().DoWork(); } catch (Exception ex) { otherThreadsException = ex; } workerThread.Stop(); manualResetEvent.Set(); }; workerThread.Start(); manualResetEvent.WaitOne(500); workerThread.Stop(); Wait.While(() => workerThread.Thread.IsAlive, 300); Assert.AreEqual(false, workerThread.Thread.IsAlive); if (otherThreadsException != null) { throw otherThreadsException; } }
public void StartShouldStartThread() { WorkerThreadManagerStub workerThreadManager = WorkerThreadManagerStub.Create(); IWorkItemQueue workItemQueue = Substitute.For <IWorkItemQueue>(); workItemQueue.Dequeue().Returns((IWorkItem)null); WorkerThread workerThread = new WorkerThread(workerThreadManager, workItemQueue, "Test", false); workerThreadManager.ShouldExitWorkerThread(workerThread, false).Returns(false); workerThread.Start(); Wait.While(() => !workerThread.Thread.IsAlive, 300); Assert.AreEqual(true, workerThread.Thread.IsAlive); workerThread.Stop(); Wait.While(() => workerThread.Thread.IsAlive, 300); Assert.AreEqual(false, workerThread.Thread.IsAlive); }
private void DoWork() { try { OnWorkerThreadStarted(); while (!m_ShouldStop) { if (m_WorkerThreadManager.ShouldExitWorkerThread(this, false)) { OnWorkerThreadExiting(WorkerThreadExitReason.MaximumThreadCountExceeded); return; } IWorkItem workItem = m_WorkItemQueue.Dequeue(); if (workItem == null) { if (m_WorkerThreadManager.ShouldExitWorkerThread(this, true)) { OnWorkerThreadExiting(WorkerThreadExitReason.WorkItemQueueIsEmpty); return; } else { if (m_StopWhenWorkItemQueueIsEmpty) { OnWorkerThreadExiting(WorkerThreadExitReason.StopWhenWorkItemQueueIsEmptyIsTrue); return; } else { continue; } } } lock (m_SyncLock) { m_CurrentWorkItem = workItem; } try { OnWorkerThreadWorkItemStarting(new WorkerThreadWorkItemStartingEventArgs(workItem)); try { workItem.DoWork(); } catch (Exception ex) { workItem.State = WorkItemState.CompletedWithException; workItem.LastException = ex; OnWorkerThreadWorkItemException(new WorkerThreadWorkItemExceptionEventArgs(workItem, ex)); } if (workItem.State == WorkItemState.CompletedWithException) { OnWorkerThreadWorkItemException(new WorkerThreadWorkItemExceptionEventArgs(workItem, workItem.LastException)); } } finally { lock (m_SyncLock) { m_CurrentWorkItem = null; OnWorkerThreadWorkItemFinished(new WorkerThreadWorkItemFinishedEventArgs(workItem)); } } } OnWorkerThreadExiting(WorkerThreadExitReason.StopMethodIsCalled); } catch (ThreadAbortException) { Stop(); // ThreadAbortException'ın tekrar fırlatılmamasını sağlar. Thread.ResetAbort(); OnWorkerThreadExiting(WorkerThreadExitReason.ThreadAborted); } catch (Exception ex) { OnWorkerThreadException(new WorkerThreadExceptionEventArgs(ex)); OnWorkerThreadExiting(WorkerThreadExitReason.ExceptionOccurred); } }