diff --git a/src/Qoollo.Turbo/Threading/QueueProcessing/DelegateQueueAsyncProcessor.cs b/src/Qoollo.Turbo/Threading/QueueProcessing/DelegateQueueAsyncProcessor.cs index fd35f26..2dc61bc 100644 --- a/src/Qoollo.Turbo/Threading/QueueProcessing/DelegateQueueAsyncProcessor.cs +++ b/src/Qoollo.Turbo/Threading/QueueProcessing/DelegateQueueAsyncProcessor.cs @@ -9,14 +9,13 @@ namespace Qoollo.Turbo.Threading.QueueProcessing { /// - /// Асинхронная обработка на делегатах. - /// Лучше не использовать, а самостоятельно наследоваться от QueueAsyncProcessor + /// Asynchronous items processor with queue. Concrete processing action passed as delegate. /// - /// Тип обрабатываемого элемента + /// Type of the elements processed by this public class DelegateQueueAsyncProcessor : QueueAsyncProcessor { /// - /// Контракты + /// Code contracts /// [ContractInvariantMethod] private void Invariant() @@ -29,82 +28,83 @@ private void Invariant() /// - /// Конструктор DelegateQueueAsyncProcessor + /// DelegateQueueAsyncProcessor constructor /// - /// Число потоков - /// Максимальный размер очереди - /// Имя для потоков - /// Будут ли потоки работать в фоновом режиме - /// Делегат обработки элементов - /// Делегат обработки исключений + /// Number of processing threads + /// The bounded size of the queue (if less or equeal to 0 then no limitation) + /// The name for this instance of and its threads + /// Whether or not processing threads are background threads + /// Delegate that will be invoked to process every item + /// Delegate that will be invoked to process unhandled exception (null is possible value) public DelegateQueueAsyncProcessor(int processorCount, int maxQueueSize, string name, bool isBackground, Action processing, Action exceptionAct) : base(processorCount, maxQueueSize, name, isBackground) { - Contract.Requires(processing != null, "processing"); + if (processing == null) + throw new ArgumentNullException(nameof(processing)); _processing = processing; _exceptionProc = exceptionAct; } /// - /// Конструктор DelegateQueueAsyncProcessor + /// DelegateQueueAsyncProcessor constructor /// - /// Число потоков - /// Максимальный размер очереди - /// Имя для потоков - /// Делегат обработки элементов - /// Делегат обработки исключений + /// Number of processing threads + /// The bounded size of the queue (if less or equeal to 0 then no limitation) + /// The name for this instance of and its threads + /// Delegate that will be invoked to process every item + /// Delegate that will be invoked to process unhandled exception (null is possible value) public DelegateQueueAsyncProcessor(int processorCount, int maxQueueSize, string name, Action processing, Action exceptionAct) : this(processorCount, maxQueueSize, name, false, processing, exceptionAct) { } /// - /// Конструктор DelegateQueueAsyncProcessor + /// DelegateQueueAsyncProcessor constructor /// - /// Число потоков - /// Максимальный размер очереди - /// Имя для потоков - /// Делегат обработки элементов + /// Number of processing threads + /// The bounded size of the queue (if less or equeal to 0 then no limitation) + /// The name for this instance of and its threads + /// Delegate that will be invoked to process every item public DelegateQueueAsyncProcessor(int processorCount, int maxQueueSize, string name, Action processing) : this(processorCount, maxQueueSize, name, false, processing, null) { } /// - /// Конструктор DelegateQueueAsyncProcessor + /// DelegateQueueAsyncProcessor constructor /// - /// Число потоков - /// Имя для потоков - /// Делегат обработки элементов - /// Делегат обработки исключений + /// Number of processing threads + /// The name for this instance of and its threads + /// Delegate that will be invoked to process every item + /// Delegate that will be invoked to process unhandled exception (null is possible value) public DelegateQueueAsyncProcessor(int processorCount, string name, Action processing, Action exceptionAct) : this(processorCount, -1, name, false, processing, exceptionAct) { } /// - /// Конструктор DelegateQueueAsyncProcessor + /// DelegateQueueAsyncProcessor constructor /// - /// Число потоков - /// Имя для потоков - /// Делегат обработки элементов + /// Number of processing threads + /// The name for this instance of and its threads + /// Delegate that will be invoked to process every item public DelegateQueueAsyncProcessor(int processorCount, string name, Action processing) : this(processorCount, -1, name, false, processing, null) { } /// - /// Конструктор DelegateQueueAsyncProcessor + /// DelegateQueueAsyncProcessor constructor /// - /// Число потоков - /// Делегат обработки элементов + /// Number of processing threads + /// Delegate that will be invoked to process every item public DelegateQueueAsyncProcessor(int processorCount, Action processing) : this(processorCount, -1, null, false, processing, null) { } /// - /// Основной метод обработки элементов + /// Processes a single item taken from the processing queue. /// - /// Элемент - /// Объект состояния, инициализированный в методе Prepare() - /// Токен для отмены обработки + /// Item to be processed + /// Thread specific state object + /// Cancellation token that will be cancelled when the immediate stop is requested protected override void Process(T element, object state, CancellationToken token) { _processing(element, token); @@ -112,11 +112,11 @@ protected override void Process(T element, object state, CancellationToken token /// - /// Обработка исключений. - /// Чтобы исключение было проброшено наверх, нужно выбросить новое исключение внутри метода. + /// Method that allows to process unhandled exceptions (e.g. logging). + /// Default behaviour - throws . /// - /// Исключение - /// Игнорировать ли исключение (false - поток завершает работу) + /// Catched exception + /// Whether the current exception can be safely skipped (false - the thread will retrow the exception) protected override bool ProcessThreadException(Exception ex) { if (_exceptionProc != null) diff --git a/src/Qoollo.Turbo/Threading/QueueProcessing/InterfaceQueueAsyncProcessor.cs b/src/Qoollo.Turbo/Threading/QueueProcessing/InterfaceQueueAsyncProcessor.cs index bb8426c..14baa6c 100644 --- a/src/Qoollo.Turbo/Threading/QueueProcessing/InterfaceQueueAsyncProcessor.cs +++ b/src/Qoollo.Turbo/Threading/QueueProcessing/InterfaceQueueAsyncProcessor.cs @@ -9,13 +9,13 @@ namespace Qoollo.Turbo.Threading.QueueProcessing { /// - /// Асинхронная обработка на интерфейсе. + /// Asynchronous items processor with queue. Concrete processing action passed by interface . /// - /// Тип обрабатываемого элемента + /// Type of the elements processed by this public class InterfaceQueueAsyncProcessor : QueueAsyncProcessor { /// - /// Контракты + /// Code contracts /// [ContractInvariantMethod] private void Invariant() @@ -26,56 +26,56 @@ private void Invariant() private readonly IQueueAsyncProcessorLogic _logic; /// - /// Конструктор InterfaceQueueAsyncProcessor + /// InterfaceQueueAsyncProcessor constructor /// - /// Интерфейс с логикой обработки данных - /// Число потоков обработки - /// Максимальный размер очереди - /// Имя, присваемое потокам - /// Будут ли потоки работать в фоновом режиме - public InterfaceQueueAsyncProcessor(IQueueAsyncProcessorLogic logic, int processorCount, int maxQueueSize, string name, bool isBackground) - : base(processorCount, maxQueueSize, name, isBackground) + /// Implementation of the item processing logic + /// Number of processing threads + /// The bounded size of the queue (if less or equeal to 0 then no limitation) + /// The name for this instance of and its threads + /// Whether or not processing threads are background threads + public InterfaceQueueAsyncProcessor(IQueueAsyncProcessorLogic logic, int threadCount, int maxQueueSize, string name, bool isBackground) + : base(threadCount, maxQueueSize, name, isBackground) { - Contract.Requires(logic != null, "logic"); + if (logic == null) + throw new ArgumentNullException(nameof(logic)); _logic = logic; } /// - /// Конструктор InterfaceQueueAsyncProcessor + /// InterfaceQueueAsyncProcessor constructor /// - /// Интерфейс с логикой обработки данных - /// Число потоков обработки - /// Максимальный размер очереди - /// Имя, присваемое потокам - public InterfaceQueueAsyncProcessor(IQueueAsyncProcessorLogic logic, int processorCount, int maxQueueSize, string name) - : this(logic, processorCount, maxQueueSize, name, false) + /// Implementation of the item processing logic + /// Number of processing threads + /// The bounded size of the queue (if less or equeal to 0 then no limitation) + /// The name for this instance of and its threads + public InterfaceQueueAsyncProcessor(IQueueAsyncProcessorLogic logic, int threadCount, int maxQueueSize, string name) + : this(logic, threadCount, maxQueueSize, name, false) { } /// - /// Конструктор InterfaceQueueAsyncProcessor + /// InterfaceQueueAsyncProcessor constructor /// - /// Интерфейс с логикой обработки данных - /// Число потоков обработки - /// Имя, присваемое потокам - public InterfaceQueueAsyncProcessor(IQueueAsyncProcessorLogic logic, int processorCount, string name) - : this(logic, processorCount, -1, name, false) + /// Implementation of the item processing logic + /// Number of processing threads + /// The name for this instance of and its threads + public InterfaceQueueAsyncProcessor(IQueueAsyncProcessorLogic logic, int threadCount, string name) + : this(logic, threadCount, -1, name, false) { } /// - /// Конструктор InterfaceQueueAsyncProcessor + /// InterfaceQueueAsyncProcessor constructor /// - /// Интерфейс с логикой обработки данных - /// Число потоков обработки - public InterfaceQueueAsyncProcessor(IQueueAsyncProcessorLogic logic, int processorCount) - : this(logic, processorCount, -1, null, false) + /// Implementation of the item processing logic + /// Number of processing threads + public InterfaceQueueAsyncProcessor(IQueueAsyncProcessorLogic logic, int threadCount) + : this(logic, threadCount, -1, null, false) { } /// - /// Создание объекта состояния на поток. - /// Вызывается при старте для каждого потока + /// Creates the state that is specific for every processing thread. Executes once for every thread during start-up. /// - /// Объект состояния + /// Created thread-specific state object protected override object Prepare() { if (_logic is IQueueAsyncProcessorLogicExt) @@ -85,9 +85,9 @@ protected override object Prepare() } /// - /// Освобождение объекта состояния потока + /// Release the thread specific state object when the thread is about to exit /// - /// Объект состояния + /// Thread-specific state object protected override void Finalize(object state) { if (_logic is IQueueAsyncProcessorLogicExt) @@ -97,22 +97,22 @@ protected override void Finalize(object state) } /// - /// Основной метод обработки элементов + /// Processes a single item taken from the processing queue. /// - /// Элемент - /// Объект состояния, инициализированный в методе Prepare() - /// Токен для отмены обработки + /// Item to be processed + /// Thread specific state object + /// Cancellation token that will be cancelled when the immediate stop is requested protected override void Process(T element, object state, CancellationToken token) { _logic.Process(element, state, token); } /// - /// Обработка исключений. - /// Чтобы исключение было проброшено наверх, нужно выбросить новое исключение внутри метода. + /// Method that allows to process unhandled exceptions (e.g. logging). + /// Default behaviour - throws . /// - /// Исключение - /// Игнорировать ли исключение (false - поток завершает работу) + /// Catched exception + /// Whether the current exception can be safely skipped (false - the thread will retrow the exception) protected override bool ProcessThreadException(Exception ex) { if (!_logic.ProcessThreadException(ex)) @@ -124,48 +124,47 @@ protected override bool ProcessThreadException(Exception ex) /// - /// Интерфейс с логикой асинхронной обработки данных + /// Specifies methods required to process the items /// - /// Тип обрабатываемого элемента + /// Type of the items [ContractClass(typeof(IQueueAsyncProcessorLogicCodeContractCheck<>))] public interface IQueueAsyncProcessorLogic { /// - /// Основной метод обработки элементов + /// Processes a single item taken from the processing queue. /// - /// Элемент - /// Объект состояния, инициализированный в методе Prepare() - /// Токен для отмены обработки + /// Item to be processed + /// Thread specific state object + /// Cancellation token that will be cancelled when the immediate stop is requested void Process(T element, object state, CancellationToken token); /// - /// Обработка исключений. - /// Чтобы исключение было проброшено наверх, нужно вернуть false, либо самостоятельно выбросить новое исключение внутри метода. + /// Method that allows to process unhandled exceptions (e.g. logging). + /// Default behaviour - throws . /// - /// Исключение - /// Игнорировать ли исключение (false - поток завершает работу) + /// Catched exception + /// Whether the current exception can be safely skipped (false - the thread will retrow the exception) bool ProcessThreadException(Exception ex); } /// - /// Интерфейс с расширенной логикой асинхронной обработки данных + /// Extended methods to process the items by /// - /// Тип обрабатываемого элемента + /// Type of the items [ContractClass(typeof(IQueueAsyncProcessorLogicExtCodeContractCheck<>))] public interface IQueueAsyncProcessorLogicExt : IQueueAsyncProcessorLogic { /// - /// Создание объекта состояния на поток. - /// Вызывается при старте для каждого потока + /// Creates the state that is specific for every processing thread. Executes once for every thread during start-up. /// - /// Объект состояния + /// Created thread-specific state object object Prepare(); /// - /// Освобождение объекта состояния потока + /// Release the thread specific state object when the thread is about to exit /// - /// Объект состояния + /// Thread-specific state object void Finalize(object state); } @@ -175,22 +174,22 @@ public interface IQueueAsyncProcessorLogicExt : IQueueAsyncProcessorLogic /// - /// Контракты + /// Code contracts /// [ContractClassFor(typeof(IQueueAsyncProcessorLogic<>))] abstract class IQueueAsyncProcessorLogicCodeContractCheck : IQueueAsyncProcessorLogic { - /// Контракты + /// Code contracts private IQueueAsyncProcessorLogicCodeContractCheck() { } - /// Контракты + /// Code contracts public bool ProcessThreadException(Exception ex) { Contract.Requires(ex != null); throw new NotImplementedException(); } - /// Контракты + /// Code contracts public void Process(T element, object state, CancellationToken token) { throw new NotImplementedException(); @@ -201,31 +200,31 @@ public void Process(T element, object state, CancellationToken token) /// - /// Контракты + /// Code contracts /// [ContractClassFor(typeof(IQueueAsyncProcessorLogicExt<>))] abstract class IQueueAsyncProcessorLogicExtCodeContractCheck : IQueueAsyncProcessorLogicExt { - /// Контракты + /// Code contracts private IQueueAsyncProcessorLogicExtCodeContractCheck() { } - /// Контракты + /// Code contracts public object Prepare() { throw new NotImplementedException(); } - /// Контракты + /// Code contracts public void Finalize(object state) { throw new NotImplementedException(); } - /// Контракты + /// Code contracts public void Process(T element, object state, CancellationToken token) { throw new NotImplementedException(); } - /// Контракты + /// Code contracts public bool ProcessThreadException(Exception ex) { throw new NotImplementedException(); diff --git a/src/Qoollo.Turbo/Threading/QueueProcessing/QueueAsyncProcessor.cs b/src/Qoollo.Turbo/Threading/QueueProcessing/QueueAsyncProcessor.cs index 1f1b7aa..0055c82 100644 --- a/src/Qoollo.Turbo/Threading/QueueProcessing/QueueAsyncProcessor.cs +++ b/src/Qoollo.Turbo/Threading/QueueProcessing/QueueAsyncProcessor.cs @@ -33,7 +33,7 @@ private void Invariant() private readonly bool _isBackground; private readonly Thread[] _procThreads; - private int _activeThreadCount; + private volatile int _activeThreadCount; private readonly Collections.Concurrent.BlockingQueue _queue; private readonly int _maxQueueSize; @@ -134,7 +134,7 @@ protected bool IsStopped get { return State == QueueAsyncProcessorState.Stopped; } } /// - /// Whether the stop was requested + /// Whether the stop was requested or already stopped /// protected bool IsStopRequestedOrStopped { @@ -145,14 +145,14 @@ protected bool IsStopRequestedOrStopped } } /// - /// Запрещено ли добавление новых задач в пул + /// Is items queue marked as Completed for Adding (no new item can be added) /// public bool IsAddingCompleted { get { return _completeAdding; } } /// - /// Можно ли закончить обработку существующих задач + /// Whether the user specified that all existed items should be processed before stop /// protected bool LetFinishedProcess { @@ -160,7 +160,7 @@ protected bool LetFinishedProcess } /// - /// Имя обработчика + /// The name for this instance of /// public string Name { @@ -168,21 +168,21 @@ public string Name } /// - /// Работают ли потоки в фоновом режиме + /// Whether or not processing threads are background threads /// public bool IsBackground { get { return _isBackground; } } /// - /// Число работающих потоков + /// Number of processing threads running right now /// protected internal int ActiveThreadCount { - get { return Volatile.Read(ref _activeThreadCount); } + get { return _activeThreadCount; } } /// - /// Число потоков обработки + /// Number of processing threads /// public int ThreadCount { @@ -190,7 +190,7 @@ public int ThreadCount } /// - /// Число элементов в очереди + /// Number of items inside processing queue /// public int ElementCount { @@ -198,7 +198,7 @@ public int ElementCount } /// - /// Ограничения на размер очереди + /// The bounded size of the queue (if less or equeal to 0 then no limitation) /// public int QueueCapacity { @@ -209,11 +209,11 @@ public int QueueCapacity /// - /// Допустима ли смена состояния + /// Verifies that state transition is possible /// - /// Старое состояние - /// Новое состояние - /// Допустим ли переход + /// Current state + /// New state + /// True when state transition can be performed private bool IsValidStateTransition(QueueAsyncProcessorState oldState, QueueAsyncProcessorState newState) { switch (oldState) @@ -233,11 +233,11 @@ private bool IsValidStateTransition(QueueAsyncProcessorState oldState, QueueAsyn } } /// - /// Безопасно сменить состояние + /// Safely changes the current state /// - /// Новое состояние - /// Состояние, которое было до смены - /// Произошла ли смена + /// New state + /// Previously observed state + /// Was state changed (false means that the state transition is not valid) private bool ChangeStateSafe(QueueAsyncProcessorState newState, out QueueAsyncProcessorState prevState) { prevState = (QueueAsyncProcessorState)Volatile.Read(ref _state); @@ -258,7 +258,7 @@ private bool ChangeStateSafe(QueueAsyncProcessorState newState, out QueueAsyncPr } /// - /// Проверить, освобождён ли объект и если да, то вызвать исключение ObjectDisposedException + /// Checks whether the current instance is in Stopped state and throws ObjectDisposedException when it is /// protected void CheckDisposed() { @@ -266,7 +266,7 @@ protected void CheckDisposed() throw new ObjectDisposedException(this.GetType().Name, "QueueAsyncProcessor is Stopped"); } /// - /// Проверить, освобождён ли объект и если да, то вызвать исключение ObjectDisposedException + /// Checks whether the current instance is in Stopped or StopRequested state and throws ObjectDisposedException when it is /// protected void CheckPendingDisposeOrDisposed() { @@ -276,9 +276,9 @@ protected void CheckPendingDisposeOrDisposed() } /// - /// Форсированно добавить элемент в очередь (игнорирует ограничения вместимости и текущее состояние) + /// Adds new item to the processing queue, even when the bounded capacity reached /// - /// Элемент + /// New item protected void AddForced(T element) { _queue.AddForced(element); @@ -286,12 +286,14 @@ protected void AddForced(T element) } /// - /// Добавить элемент на обработку + /// Attempts to add new item to processing queue /// - /// Элемент - /// Таймаут добавления в миллисекундах - /// Токен отмены - /// Успешность (удалось ли добавить до истечения таймаута) + /// New item + /// Adding timeout in milliseconds + /// Cancellation token + /// True if item was added, otherwise false + /// + /// public override bool Add(T element, int timeout, CancellationToken token) { CheckDisposed(); @@ -309,8 +311,10 @@ public override bool Add(T element, int timeout, CancellationToken token) /// - /// Запуск обработчиков + /// Starts all processing threads and changes state to /// + /// Object was disposed + /// Can't start processor because it is not in state public virtual void Start() { QueueAsyncProcessorState prevState; @@ -357,9 +361,9 @@ public virtual void Start() } /// - /// Получить токен отмены, срабатывающий при запросе остановки (в том числе и отложенной) + /// Gets the CancellationToken that will be cancelled when a stop is requested /// - /// Токен отмены + /// Cancellation token protected CancellationToken GetStopRequestedCancellationToken() { var tokenSrc = this._stopRequestedCancelation; @@ -368,9 +372,9 @@ protected CancellationToken GetStopRequestedCancellationToken() return new CancellationToken(true); } /// - /// Получить токен отмены, срабатывающий при запросе немеделнной остановки + /// Gets the CancellationToken that will be cancelled when a stop should be completed immediately (without flag) /// - /// Токен отмены + /// Cancellation token protected CancellationToken GetStoppedCancellationToken() { var tokenSrc = this._stoppedCancelation; @@ -381,7 +385,7 @@ protected CancellationToken GetStoppedCancellationToken() /// - /// Основная функция, выполняемая потоками + /// Main thread procedure /// [System.Diagnostics.DebuggerNonUserCode] private void ThreadProcFunc() @@ -505,11 +509,11 @@ private void ThreadProcFunc() /// - /// Обработка исключений. - /// Чтобы исключение было проброшено наверх, нужно выбросить новое исключение внутри метода. + /// Method that allows to process unhandled exceptions (e.g. logging). + /// Default behaviour - throws . /// - /// Исключение - /// Игнорировать ли исключение (false - поток завершает работу) + /// Catched exception + /// Whether the current exception can be safely skipped (false - the thread will retrow the exception) protected virtual bool ProcessThreadException(Exception ex) { Contract.Requires(ex != null); @@ -518,35 +522,36 @@ protected virtual bool ProcessThreadException(Exception ex) } /// - /// Создание объекта состояния на поток. - /// Вызывается при старте для каждого потока + /// Creates the state that is specific for every processing thread. Executes once for every thread during start-up. /// - /// Объект состояния + /// Created thread-specific state object protected virtual object Prepare() { return null; } /// - /// Основной метод обработки элементов. - /// Токен отменяется только при запросе немедленной остановки. - /// Остановка может быть отложенной, тогда нужно проверять текущее состояние. + /// Processes a single item taken from the processing queue. /// - /// Элемент - /// Объект состояния, инициализированный в методе Prepare() - /// Токен для отмены обработки при вызове Stop + /// + /// Cancellation token is cancelled only when immediate stop is requested (LetFinishProcess is false). + /// For that case it is improtant to manually check for state or use token from . + /// + /// Item to be processed + /// Thread specific state object initialized by method + /// Cancellation token that will be cancelled when the immediate stop is requested (see ) protected abstract void Process(T element, object state, CancellationToken token); /// - /// Освобождение объекта состояния потока + /// Release the thread specific state object when the thread is about to exit /// - /// Объект состояния + /// Thread-specific state object protected virtual void Finalize(object state) { } /// - /// Запретить добавление элементов + /// Marks that new items cannot be added to processing queue /// public void CompleteAdding() { @@ -554,7 +559,7 @@ public void CompleteAdding() } /// - /// Ожидание полной остановки + /// Blocks the current thread and waits for all processing threads to complete /// public void WaitUntilStop() { @@ -565,10 +570,10 @@ public void WaitUntilStop() } /// - /// Ожидание полной остановки с таймаутом + /// Blocks the current thread and waits for all processing threads to complete /// - /// Таймаут ожидания в миллисекундах - /// true - дождались, false - вышли по таймауту + /// Waiting timeout in milliseconds + /// True when all threads completed in time public bool WaitUntilStop(int timeout) { if (State == QueueAsyncProcessorState.Stopped) @@ -579,12 +584,12 @@ public bool WaitUntilStop(int timeout) /// - /// Остановка работы асинхронного обработчика + /// Stops processing of items and changes state to /// - /// Ждать ли завершения всех потоков - /// Позволить закончить обработку того, что есть в очереди - /// Заблокировать добавление новых элементов - /// Запущен ли процесс остановки + /// Whether the current thread should be blocked until all processing threads are be completed + /// Whether all items that have already been added must be processed before stopping + /// Marks that new items cannot be added to processing queue + /// Is stopping process triggered private bool StopProcessor(bool waitForStop, bool letFinishProcess, bool completeAdding) { if (this.IsStopRequestedOrStopped) @@ -670,11 +675,11 @@ private bool StopProcessor(bool waitForStop, bool letFinishProcess, bool complet /// - /// Остановка и освобождение ресурсов + /// Stops processing of items and changes state to /// - /// Ожидать остановки - /// Позволить обработать всю очередь - /// Запретить добавление новых элементов + /// Whether the current thread should be blocked until all processing threads are be completed + /// Whether all items that have already been added must be processed before stopping + /// Marks that new items cannot be added to processing queue public virtual void Stop(bool waitForStop, bool letFinishProcess, bool completeAdding) { StopProcessor(waitForStop, letFinishProcess, completeAdding); @@ -682,7 +687,7 @@ public virtual void Stop(bool waitForStop, bool letFinishProcess, bool completeA } /// - /// Остановка и освобождение ресурсов + /// Stops processing of items and changes state to /// public void Stop() { @@ -690,14 +695,14 @@ public void Stop() } /// - /// Основной код освобождения ресурсов + /// Cleans-up resources /// - /// Вызвано ли освобождение пользователем. False - деструктор + /// Is it called explicitly by user (False - from finalizer) protected override void Dispose(bool isUserCall) { if (!this.IsStopRequestedOrStopped) { - Debug.Assert(isUserCall, "QueueAsyncProcessor destructor: Better to dispose by user. Закомментируй, если не нравится."); + Debug.Assert(isUserCall, "QueueAsyncProcessor destructor: Better to dispose by user"); if (isUserCall) StopProcessor(true, false, true); @@ -717,12 +722,14 @@ protected override void Dispose(bool isUserCall) base.Dispose(isUserCall); } +#if DEBUG /// - /// Финализатор + /// Finalizer /// ~QueueAsyncProcessor() { Dispose(false); } +#endif } }