Ejemplo n.º 1
0
            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);
            }
Ejemplo n.º 2
0
            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);
            }
Ejemplo n.º 3
0
            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);
            }
Ejemplo n.º 4
0
            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);
        }