What is PCR?

Port Concurrency Runtime (PCR) is a Port-Based asyncronous message passing library.

Simply put, you push messages to ports and the messages are processed (i.e popped) asyncronously using handlers which we call Selectors. All messages (i.e. objects) are sent and received via a Port. Selectors are user defined message handlers that can atomically process a single message or multiple messages from one or more ports based on rules defined by the Selector. The library includes common selectors that should satisfy the most common patterns such as SelectOne, SelectMany, Choice, Interleave, and Join.

        /// <summary>
        /// Test single item selector. SelectOne "can" have a FIFO gaureentee (depending on other factors defined by usage). In this case, only one
        /// selector will be scheduled at a time, but can also be set to run concurrent. The selector will run again when a message is pushed on port.
        /// </summary>
        static void SelectOneTest()
        {
            // Create a port and add some items.
            Port<string> p = new Port<string>();
            for (int i = 0; i < 20; i++)
                p.Push(i.ToString("00"));
            int activeCount = 0;

            // Create and activate the selector.
            Selector.SelectOne<string>(true, p,
                delegate(string s)
                {
                    if ( Interlocked.Increment(ref activeCount) > 1 )
                        Console.WriteLine("Error: active count should never go above 1.");
                    Console.WriteLine("SelectOneTest: {0} ThreadID:{1:00} Active:{2}", s, Thread.CurrentThread.ManagedThreadId, activeCount);
                    Thread.Sleep(10);
                    Interlocked.Decrement(ref activeCount);
                }).Add(); 
        }


The above code shows the general pattern that will be used by all selectors. A port is created, messages are added, and we register a selector query to process messages when they arrive on the port. The PCR runtime handles invoking the selector(s) registered with the port based on the selector rules and message availability. So a selector could run right away or not at all. More complex patterns such as selecting from many ports (i.e. a Join) or selecting many messages from a single port follow the same pattern. Things like Where filters are as simple as supplying a predicate delegate to a selector.
Helpful Links

--
William Stacey [C# MVP]

Last edited Jan 30, 2007 at 3:20 PM by staceyw, version 33