private void OperationProc(object state) { var operationInWorkState = (OperationInWorkState)state; var newOperationInWorkState = new OperationInWorkState(operationInWorkState.Operation, Thread.CurrentThread); this.operationsInWork.TryUpdate(operationInWorkState.Operation.Id, newOperationInWorkState, operationInWorkState); try { Log.Debug("Started operation in thread " + Thread.CurrentThread.ManagedThreadId); operationInWorkState.Operation.Invoke(); Log.Debug("Ended operation in thread " + Thread.CurrentThread.ManagedThreadId); } catch (Exception ex) { Log.Error("Operation execution error in thread " + Thread.CurrentThread.ManagedThreadId, ex); throw; } finally { this.operationsInWork.TryRemove(operationInWorkState.Operation.Id, out operationInWorkState); Interlocked.Decrement(ref this.runningThreads); this.simultaneouslyRunningLimit.Set(); } }
private void OperationsLoop(object state) { Log.Debug("Started operation loop in thread " + Thread.CurrentThread.ManagedThreadId); do { lock (this.operationLoopSync) { if (!(this.operationLoop = !this.stop && !this.operationQueue.IsEmpty)) { // Wait before all sub threads are done. if (this.runningThreads > 0) { this.simultaneouslyRunningLimit.Reset(); this.operationLoop = true; } else { break; } } } if (this.pause) { this.simultaneouslyRunningLimit.Reset(); } // Here waiting opration add or available free thread. this.simultaneouslyRunningLimit.Wait(); if (this.stop || this.pause) { continue; } var possibleMaxThreads = this.GetPossibleMaxThreads(); // If system cannot run simultaneously one more thread or queue is empty then sleep on wait. if ((this.runningThreads == 0 && possibleMaxThreads <= this.runningThreads) || this.operationQueue.IsEmpty) { this.simultaneouslyRunningLimit.Reset(); continue; } MultiThreadExecutorOperation operation; // If can not take operation in the processing then spend time on loop turn :o). if (this.operationQueue.TryDequeue(out operation)) { Interlocked.Increment(ref this.runningThreads); var operationInWorkState = new OperationInWorkState(operation, null); this.operationsInWork.TryAdd(operation.Id, operationInWorkState); ThreadPool.QueueUserWorkItem(this.OperationProc, operationInWorkState); } }while (true); Log.Debug("Ended operation loop in thread " + Thread.CurrentThread.ManagedThreadId); }