Пример #1
0
 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}));
 }
Пример #2
0
 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;
 }