private void CompressChunk( CompressionMode compressionMode, AsyncReadContext <QueueItem> asyncReadContext, ConcurrentDictionary <int, byte[]> resultPieces, CancellationTokenSource exceptionSrc, CancellationToken[] cancellationTokens, ManualResetEventSlim outputOverflowEvent) { try { while (!cancellationTokens.Any(ct => ct.IsCancellationRequested) || asyncReadContext.Queue.Count > 0) { outputOverflowEvent.Wait(); if (!asyncReadContext.Queue.TryTake(out var queueItem)) { asyncReadContext.EmptyInputEvent.Reset(); asyncReadContext.EmptyInputEvent.Wait(TimeSpan.FromMilliseconds(10)); continue; } byte[] data; switch (compressionMode) { case CompressionMode.Compress: data = _compressionService.Compress(queueItem.Data); break; case CompressionMode.Decompress: data = _compressionService.Decompress(queueItem.Data); break; default: throw new ApplicationException($"Managing of compression mode '{compressionMode}' not implemented'"); } resultPieces.AddOrUpdate(queueItem.Order, data, (i1, byteArray) => byteArray); ControlInputOverflow(asyncReadContext.Queue, asyncReadContext.InputOverflowEvent); } } catch (Exception e) { _statusUpdateService.Error(e.Message); exceptionSrc.Cancel(); } }
public ParallelCompressionContext Run(CompressionMode compressionMode, int threadsCount, AsyncReadContext <QueueItem> asyncReadContext) { var threads = new List <Thread>(threadsCount); var resultsDictionary = new ConcurrentDictionary <int, byte[]>(); var exceptionSrc = new CancellationTokenSource(); var tokens = new [] { asyncReadContext.ReadFinishedSource.Token, asyncReadContext.ExceptionSource.Token, exceptionSrc.Token }; var outputOverflowEvent = new ManualResetEventSlim(true); for (int i = 0; i < threadsCount; i++) { var thread = new Thread(() => CompressChunk(compressionMode, asyncReadContext, resultsDictionary, exceptionSrc, tokens.ToArray(), outputOverflowEvent)); threads.Add(thread); thread.Start(); } return(new ParallelCompressionContext(threads, resultsDictionary, exceptionSrc, outputOverflowEvent)); }