public LongRunningWork SetWorkForThread(Action <object> action, object state, string name) { _action = action; _state = state; _name = name; _workIsDone = new LongRunningWork(new ManualResetEvent(false), name); _waitForWork.Set(); return(_workIsDone); }
public LongRunningWork SetWorkForThread(Action <object> action, object state, string name) { _action = action; _state = state; _name = name; Debug.Assert(_workIsDone == null, "_workIsDone must be null here"); var workIsDone = new LongRunningWork(new ManualResetEvent(false), name); _workIsDone = workIsDone; _waitForWork.Set(); return(workIsDone); }
private bool DoWork() { _workIsDone.ManagedThreadId = Thread.CurrentThread.ManagedThreadId; if (_action == null) { // should only happen when we shutdown return(false); } ResetCurrentThreadName(); Thread.CurrentThread.Name = _name; try { _workIsDone.CurrentThreadStats = NativeMemory.CurrentThreadStats; LongRunningWork.Current = _workIsDone; _action(_state); } catch (Exception e) { if (_log.IsOperationsEnabled) { _log.Operations($"An uncaught exception occurred in '{_name}' and killed the process", e); } throw; } finally { _workIsDone.Set(); LongRunningWork.Current = null; } _action = null; _state = null; _workIsDone = null; NativeMemory.CurrentThreadStats.CurrentlyAllocatedForProcessing = 0; ThreadLocalCleanup.Run(); ResetCurrentThreadName(); Thread.CurrentThread.Name = "Available Pool Thread"; var resetThread = ResetThreadPriority(); resetThread &= ResetThreadAffinity(); if (resetThread == false) { return(false); } _waitForWork.Reset(); lock (_parent) { if (_parent._disposed) { return(false); } if (_parent._lowMemoryFlag.IsRaised()) { SetWorkForThread(null, null, null); return(false); } _parent._pool.Enqueue(this); } return(true); }
public void Run() { try { InitializeProcessThreads(); LongRunningWork.CurrentPooledThread = this; while (true) { _waitForWork.WaitOne(); _workIsDone.ManagedThreadId = Thread.CurrentThread.ManagedThreadId; if (_action == null) { return; // should only happen when we shutdown } ResetCurrentThreadName(); Thread.CurrentThread.Name = _name; try { LongRunningWork.Current = _workIsDone; _action(_state); } catch (Exception e) { if (_log.IsOperationsEnabled) { _log.Operations($"An uncaught exception occurred in '{_name}' and killed the process", e); } throw; } finally { _workIsDone.Set(); LongRunningWork.Current = null; } _action = null; _state = null; _workIsDone = null; ThreadLocalCleanup.Run(); ResetCurrentThreadName(); Thread.CurrentThread.Name = "Available Pool Thread"; if (ResetThreadPriority() == false) { return; } if (ResetThreadAffinity() == false) { return; } _waitForWork.Reset(); lock (_parent) { if (_parent._disposed) { return; } _parent._pool.Enqueue(this); } } } finally { NativeMemory.NotifyCurrentThreadAboutToClose(); } }
public void ReaddSpecificErrors() { // ARRANGE var workerThreads = 1; var worker = new BackgroundWorkerQueue(workerThreads); var exceptionThrowingWork = new ExceptionThrowingWork(); var longRunningWorkProcessing = new LongRunningWork(); var longRunningWorkInBacklog = new LongRunningWork(); worker.Enqueue(exceptionThrowingWork); worker.Enqueue(longRunningWorkProcessing); worker.Enqueue(longRunningWorkInBacklog); // wait for a bit Thread.Sleep(500); var status = worker.Status(); // PRECONDITIONS ASSERT CollectionAssert.IsNotEmpty(status.Failed); // ACT worker.ReAddFailed(new List<IWork>() { exceptionThrowingWork }); // ASSERT var actual = worker.Status(); CollectionAssert.IsEmpty(actual.Failed); CollectionAssert.Contains(actual.Processing, longRunningWorkProcessing); CollectionAssert.Contains(actual.Backlog, longRunningWorkInBacklog); CollectionAssert.Contains(actual.Backlog, exceptionThrowingWork); }
public void Status() { // Arrange var workerThreads = 2; var worker = new BackgroundWorkerQueue(workerThreads); var exceptionThrowingWork1 = new ExceptionThrowingWork(); var exceptionThrowingWork2 = new ExceptionThrowingWork(); var longRunningWork1 = new LongRunningWork(); var longRunningWork2 = new LongRunningWork(); var work1 = new StandardWork(); var work2 = new StandardWork(); // Act worker.Enqueue(exceptionThrowingWork1); worker.Enqueue(exceptionThrowingWork2); worker.Enqueue(longRunningWork1); worker.Enqueue(longRunningWork2); worker.Enqueue(work1); worker.Enqueue(work2); // wait for a bit Thread.Sleep(1000); var actual = worker.Status(); // Assert //backlog CollectionAssert.AreEquivalent(new List<IWork>() { work1, work2 }, actual.Backlog); //failed CollectionAssert.AreEquivalent( new List<IWork>() { exceptionThrowingWork1, exceptionThrowingWork2 }, actual.Failed); //processing CollectionAssert.AreEquivalent(new List<IWork>() { longRunningWork1, longRunningWork2 }, actual.Processing); }