public void TestSeveralChannelsInAPipeline() { Channel<uint> incoming = new Channel<uint>(5); Channel<uint> filteredEven = new Channel<uint>(9); Channel<uint> filteredDivisibleBy3 = new Channel<uint>(4); Channel<ClassifiedNumber> classifiedNumbers = new Channel<ClassifiedNumber>(10); Channel<int> quitChannel = new Channel<int>(2); Thread feederThread = new Thread( ()=> { for (uint i = 0; i!=90; ++i) { incoming.Send(i); } }); Thread filterThread = new Thread( ()=> { bool done = false; while (!done) { Channel.Select( incoming.CaseReceive( v => { if (v%2==0) { filteredEven.Send(v); } else if (v%3==0) { filteredDivisibleBy3.Send(v); } } ), quitChannel.CaseReceive( v => done = true )); } }); Thread mergeThread = new Thread( () => { bool done = false; while (!done) { Channel.Select( filteredEven.CaseReceive( v=>classifiedNumbers.Send(new ClassifiedNumber{Value=v, Category = "even"})), filteredDivisibleBy3.CaseReceive( v=>classifiedNumbers.Send(new ClassifiedNumber{Value=v, Category = "div3"})), quitChannel.CaseReceive( v=>done = true)); } }); feederThread.Start(); filterThread.Start(); mergeThread.Start(); List<uint> outputEvenNumbers = new List<uint>(); List<uint> outputDivisibleBy3Numbers = new List<uint>(); for (int idx=0; idx != 60; ++idx) { var number = classifiedNumbers.Receive(); switch (number.Category) { case "even": outputEvenNumbers.Add(number.Value); break; case "div3": outputDivisibleBy3Numbers.Add(number.Value); break; } } quitChannel.Send(0); quitChannel.Send(0); feederThread.Join(); filterThread.Join(); mergeThread.Join(); Assert.That( outputEvenNumbers, Is.EqualTo(new List<uint>{0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88})); Assert.That( outputDivisibleBy3Numbers, Is.EqualTo(new List<uint>{3,9,15,21,27,33,39,45,51,57,63,69,75,81,87})); }
public int RunConsole() { int exitCode = 0; Channel<string> commandChannel = new Channel<string>(1); Channel<string> readyChannel = new Channel<string>(1); Thread consoleThread = new Thread( () => { while (true) { string prompt = readyChannel.Receive(); if (prompt == null) { return; } Console.Write(prompt); commandChannel.Send(Console.ReadLine()); } }) {IsBackground = true}; consoleThread.Start(); while (Running) { readyChannel.Send(Prompt); Channel.Select( iQuitChannel.CaseReceive(aExitCode => { Running = false; exitCode = aExitCode; }), commandChannel.CaseReceive(aCommand => { if (aCommand == null) { Running = false; EndOfInput = true; return; } iCommandProcessor.ProcessCommand(aCommand); })); } readyChannel.Send(null); return exitCode; }