Ejemplo n.º 1
0
        private void ThreadProcFunc()
        {
            CancellationToken stopRequestedToken = GetStopRequestedCancellationToken();
            CancellationToken stoppedToken       = GetStoppedCancellationToken();

            object state = null;

            try
            {
                Interlocked.Increment(ref _activeThreadCount);
                Profiling.Profiler.QueueAsyncProcessorThreadStart(this.Name, this.ActiveThreadCount, this.ThreadCount);

                state = this.Prepare();
                Profiling.ProfilingTimer timer = new Profiling.ProfilingTimer();
                timer.StartTime();


                while (!stopRequestedToken.IsCancellationRequested)
                {
                    try
                    {
                        T elem = default(T);
                        while (!stopRequestedToken.IsCancellationRequested)
                        {
                            elem = default(T);
                            if (TryTakeFromQueue(out elem, Timeout.Infinite, stopRequestedToken))
                            {
                                if (Profiling.Profiler.IsProfilingEnabled)
                                {
                                    Profiling.Profiler.QueueAsyncProcessorElementCountDecreased(this.Name, ElementCount, QueueCapacity);
                                }

                                timer.RestartTime();

                                this.Process(elem, state, stoppedToken);

                                if (Profiling.Profiler.IsProfilingEnabled)
                                {
                                    Profiling.Profiler.QueueAsyncProcessorElementProcessed(this.Name, timer.GetTime());
                                }
                            }
                            else
                            {
                                TurboContract.Assert(stopRequestedToken.IsCancellationRequested, conditionString: "stopRequestedToken.IsCancellationRequested");
                            }
                        }
                    }
                    catch (OperationCanceledException opEx)
                    {
                        if (!stopRequestedToken.IsCancellationRequested)
                        {
                            if (!ProcessThreadException(opEx))
                            {
                                throw;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (ex.GetType() == typeof(ThreadAbortException) || ex.GetType() == typeof(ThreadInterruptedException) || ex.GetType() == typeof(StackOverflowException) || ex.GetType() == typeof(OutOfMemoryException))
                        {
                            throw;
                        }

                        if (!ProcessThreadException(ex))
                        {
                            throw;
                        }
                    }
                }


                if (_letFinishProcess)
                {
                    while (!stoppedToken.IsCancellationRequested)
                    {
                        try
                        {
                            T elem = default(T);
                            while (!stoppedToken.IsCancellationRequested && TryTakeFromQueue(out elem))
                            {
                                if (Profiling.Profiler.IsProfilingEnabled)
                                {
                                    Profiling.Profiler.QueueAsyncProcessorElementCountDecreased(this.Name, ElementCount, QueueCapacity);
                                }

                                timer.RestartTime();
                                this.Process(elem, state, stoppedToken);
                                if (Profiling.Profiler.IsProfilingEnabled)
                                {
                                    Profiling.Profiler.QueueAsyncProcessorElementProcessed(this.Name, timer.GetTime());
                                }
                            }

                            if (_queue.Count == 0)
                            {
                                break;
                            }
                        }
                        catch (OperationCanceledException opEx)
                        {
                            if (!stoppedToken.IsCancellationRequested)
                            {
                                if (!ProcessThreadException(opEx))
                                {
                                    throw;
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            if (ex.GetType() == typeof(ThreadAbortException) || ex.GetType() == typeof(ThreadInterruptedException) || ex.GetType() == typeof(StackOverflowException) || ex.GetType() == typeof(OutOfMemoryException))
                            {
                                throw;
                            }

                            if (!ProcessThreadException(ex))
                            {
                                throw;
                            }
                        }
                    }
                }
            }
            finally
            {
                this.Finalize(state);

                if (Interlocked.Decrement(ref _activeThreadCount) <= 0)
                {
                    // Вынуждены ждать
                    SpinWait sw = new SpinWait();
                    while (State == QueueAsyncProcessorState.StartRequested)
                    {
                        sw.SpinOnce();
                    }

                    if (State == QueueAsyncProcessorState.StopRequested)
                    {
                        QueueAsyncProcessorState prevState;
                        if (ChangeStateSafe(QueueAsyncProcessorState.Stopped, out prevState))
                        {
                            TurboContract.Assert(prevState == QueueAsyncProcessorState.StopRequested, conditionString: "prevState == QueueAsyncProcessorState.StopRequested");
                            _stoppedEvent.Set();
                            this.DisposeQueue(); // Can throw exception
                            Profiling.Profiler.QueueAsyncProcessorDisposed(this.Name, false);
                        }
                    }
                }

                Profiling.Profiler.QueueAsyncProcessorThreadStop(this.Name, this.ActiveThreadCount, this.ThreadCount);
            }
        }