andrew4582

TransferStream

Aug 19th, 2011
255
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.46 KB | None | 0 0
  1. //--------------------------------------------------------------------------
  2. //
  3. //  Copyright (c) Microsoft Corporation.  All rights reserved.
  4. //
  5. //  File: TransferStream.cs
  6. //
  7. //--------------------------------------------------------------------------
  8.  
  9. using System.Collections.Concurrent;
  10. using System.IO;
  11. using System.Threading.Tasks;
  12.  
  13. namespace System.Threading
  14. {
  15.     /// <summary>Writeable stream for using a separate thread in a producer/consumer scenario.</summary>
  16.     public sealed class TransferStream : AbstractStreamBase
  17.     {
  18.         /// <summary>The underlying stream to target.</summary>
  19.         private Stream _writeableStream;
  20.         /// <summary>The collection of chunks to be written.</summary>
  21.         private BlockingCollection<byte[]> _chunks;
  22.         /// <summary>The Task to use for background writing.</summary>
  23.         private Task _processingTask;
  24.  
  25.         /// <summary>Initializes a new instance of the TransferStream.</summary>
  26.         /// <param name="writeableStream">The underlying stream to which to write.</param>
  27.         public TransferStream(Stream writeableStream)
  28.         {
  29.             // Validate arguments
  30.             if (writeableStream == null) throw new ArgumentNullException("writeableStream");
  31.             if (!writeableStream.CanWrite) throw new ArgumentException("Target stream is not writeable.");
  32.  
  33.             // Set up the producer/consumer relationship, including starting the consumer running
  34.             _writeableStream = writeableStream;
  35.             _chunks = new BlockingCollection<byte[]>();
  36.             _processingTask = Task.Factory.StartNew(() =>
  37.             {
  38.                 // Write out all chunks to the underlying stream
  39.                 foreach (var chunk in _chunks.GetConsumingEnumerable())
  40.                     _writeableStream.Write(chunk, 0, chunk.Length);
  41.  
  42.             }, TaskCreationOptions.LongRunning);
  43.         }
  44.  
  45.         /// <summary>Determines whether data can be written to the stream.</summary>
  46.         public override bool CanWrite { get { return true; } }
  47.  
  48.         /// <summary>Writes a sequence of bytes to the stream.</summary>
  49.         /// <param name="buffer">An array of bytes. Write copies count bytes from buffer to the stream.</param>
  50.         /// <param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the stream.</param>
  51.         /// <param name="count">The number of bytes to be written to the current stream.</param>
  52.         public override void Write(byte[] buffer, int offset, int count)
  53.         {
  54.             // Validate all arguments
  55.             if (buffer == null) throw new ArgumentNullException("buffer");
  56.             if (offset < 0 || offset >= buffer.Length) throw new ArgumentOutOfRangeException("offset");
  57.             if (count < 0 || offset + count > buffer.Length) throw new ArgumentOutOfRangeException("count");
  58.             if (count == 0) return;
  59.  
  60.             // Store the data to the collection
  61.             var chunk = new byte[count];
  62.             Buffer.BlockCopy(buffer, offset, chunk, 0, count);
  63.             _chunks.Add(chunk);
  64.         }
  65.  
  66.         /// <summary>Closes the stream and releases all resources associated with it.</summary>
  67.         public override void Close()
  68.         {
  69.             // Complete the collection and waits for the consumer to process all of the data
  70.             _chunks.CompleteAdding();
  71.             try { _processingTask.Wait(); }
  72.             finally { base.Close(); }
  73.         }
  74.     }
  75. }
Add Comment
Please, Sign In to add comment