private void ThreadWork() { try { while (!EndCondition) { if (isStopping) { Complete(); return; } long numOfBlock = 0; if (inputQueue.TryTake(out var dataBlock)) { var result = new DataBlock(dataBlock.Index, blockGZipper.Execute(dataBlock.BlockBytes)); numOfBlock = result.Index; while (!outputQueue.TryAdd(result)) { logger.Debug($"Thread number {Thread.CurrentThread.ManagedThreadId} " + $"trying add block {numOfBlock} to queue"); while (!outputQueue.CanAdd.WaitOne(WAIT_FOR_ADD_BLOCK_TIMEOUT)) { if (isStopping || EndCondition) { Complete(); return; } } } logger.Debug($"Thread number {Thread.CurrentThread.ManagedThreadId} " + $"added gzipped block {numOfBlock} to queue"); } else { logger.Debug($"Thread {Thread.CurrentThread.ManagedThreadId} " + $"waiting for cantake signal"); outputQueue.CanTake.WaitOne(WAIT_FOR_BLOCK_TIMEOUT); } } Complete(); } catch (Exception ex) { OnErrorOccured(ex); } }