private void ProcessParts(BlockingQueue <byte[]> inputBlockingQueue,
                                  BlockingQueue <BlockingWorkItem <byte[]> > outputBlockingQueue,
                                  Cancellation cancellation = null)
        {
            var threadPool = new StaticThreadPool();

            new Thread(() =>
            {
                while (inputBlockingQueue.Dequeue(out var item))
                {
                    if (cancellation?.IsCancelled() ?? false)
                    {
                        break;
                    }

                    var blockingWorkItem = new BlockingWorkItem <byte[]>();
                    outputBlockingQueue.Enqueue(blockingWorkItem);

                    var part = item;
                    threadPool.QueueJob(() =>
                    {
                        var processed = ProcessPart(part);
                        blockingWorkItem.SetResult(processed);
                    });
                }
                outputBlockingQueue.Complete();
            }).Start();
        }
        private void WriteByParts(BlockingQueue <BlockingWorkItem <byte[]> > inputBlockingQueue,
                                  Action onFinished,
                                  Cancellation cancellation = null)
        {
            new Thread(() =>
            {
                _target.WriteByParts(CompressedParts());

                if (!cancellation.IsCancelled())
                {
                    onFinished();
                }

                IEnumerable <byte[]> CompressedParts()
                {
                    while (inputBlockingQueue.Dequeue(out var part))
                    {
                        if (cancellation?.IsCancelled() ?? false)
                        {
                            yield break;
                        }

                        yield return(part.GetResult());
                    }
                }
            }).Start();
        }
        private void ReadByParts(BlockingQueue <byte[]> outputBlockingQueue,
                                 Cancellation cancellation = null)
        {
            new Thread(() =>
            {
                var parts = PartsStream();
                foreach (var part in parts)
                {
                    if (cancellation?.IsCancelled() ?? false)
                    {
                        break;
                    }

                    outputBlockingQueue.Enqueue(part);
                }
                outputBlockingQueue.Complete();
            }).Start();
        }