/// <summary>Runs the two specified processes in parallel, allowing one to generate data by writing it to a stream, and the other to consume the data by reading it from a stream.</summary> /// <param name="writingAction">An action that generates data and writes it to a stream.</param> /// <param name="readingAction">An action that will want to read information from a stream.</param> public static void RunCostreams(Action<Stream> writingAction, Action<Stream> readingAction) { // Everything the writingAction writes will be enqueued in here and dequeued by the readingAction var queue = new Queue<byteChunk>(); using (var hasData = new ManualResetEvent(false)) { var writer = new writingCostream(queue, hasData); var reader = new readingCostream(queue, hasData); // Start reading in a new thread. The first call to reader.Read() will block until there is something in the queue to read. var thread = new Thread(() => readingAction(reader)); thread.Start(); // Start writing. Calls to writer.Write() will place the data in the queue and signal the reading thread. writingAction(writer); // Insert a null at the end of the queue to signal to the reader that this is where the data ends. lock (queue) { queue.Enqueue(null); hasData.Set(); } // Wait for the reader to consume all the remaining data. thread.Join(); } }
/// <summary>Runs the two specified processes in parallel, allowing one to generate data by writing it to a stream, and the other to consume the data by reading it from a stream.</summary> /// <param name="writingAction">An action that generates data and writes it to a stream.</param> /// <param name="readingAction">An action that will want to read information from a stream.</param> public static void RunCostreams(Action <Stream> writingAction, Action <Stream> readingAction) { // Everything the writingAction writes will be enqueued in here and dequeued by the readingAction var queue = new Queue <byteChunk>(); using (var hasData = new ManualResetEvent(false)) { var writer = new writingCostream(queue, hasData); var reader = new readingCostream(queue, hasData); // Start reading in a new thread. The first call to reader.Read() will block until there is something in the queue to read. var thread = new Thread(() => readingAction(reader)); thread.Start(); // Start writing. Calls to writer.Write() will place the data in the queue and signal the reading thread. writingAction(writer); // Insert a null at the end of the queue to signal to the reader that this is where the data ends. lock (queue) { queue.Enqueue(null); hasData.Set(); } // Wait for the reader to consume all the remaining data. thread.Join(); } }