protected override void WriteToDisk() { try { using (var outFileStream = new FileStream(OutFileName, FileMode.Create)) { OutFileStream = outFileStream; //write all decompressed data chunks to disk for (var chunkNumber = 0; !(IncomingFinished && chunkNumber == ChunkCounter); chunkNumber++) { if (StopRequested) { return; } //waiting for the next chunk to write to disk while (true) { if (StopRequested) { return; } KeyValuePair <int, byte[]> chunk; lock (Locker) chunk = OutgoingChunks.FirstOrDefault(b => b.Key == chunkNumber); if (chunk.Value != null) { outFileStream.Write(chunk.Value, 0, chunk.Value.Length); lock (Locker) OutgoingChunks.Remove(chunk.Key); //force gc cleanup of processed bytes GC.Collect(2, GCCollectionMode.Forced); break; } Thread.Sleep(100); } } var elapsed = DateTime.Now - StartTime; Console.Write("Decompression was completed. Elapsed time is {0}ms", elapsed); } } catch (Exception ex) { StopRequested = true; Console.Write("There is the problem at the decompression process:{0}", ex.Message); } }
//compress data chunk protected override void ProcessChunk(int chunkNumber) { if (StopRequested) { return; } ProcessSemaphore.WaitOne(); try { KeyValuePair <int, byte[]> chunk; lock (Locker) chunk = IncomingChunks.FirstOrDefault(b => b.Key == chunkNumber); //stream for processed data using (var outMemStream = new MemoryStream()) { using (var zipStream = new GZipStream(outMemStream, CompressionMode.Compress)) { using (var inMemStream = new MemoryStream(chunk.Value, 0, chunk.Value.Length)) { inMemStream.CopyTo(zipStream); } } //compressed bytes var bytes = outMemStream.ToArray(); lock (Locker) { //add new data chunk to collection of compressed data OutgoingChunks.Add(chunkNumber, bytes); //remove chunk from collection of uncompressed data IncomingChunks.Remove(chunkNumber); } } } catch (Exception ex) { StopRequested = true; Console.Write("There is an exception at the compressing process: {0}", ex.Message); } ProcessSemaphore.Release(); //if this is the first chunk - start writing to disk in a separate thread if (chunkNumber == 0 && WritingThread.ThreadState != ThreadState.Running && !StopRequested) { WritingThread.Start(); } }