Пример #1
0
        /// <summary>
        /// Reads input and applies the method to each input, and emits the output
        /// </summary>
        /// <param name="method">The worker method to apply to each element.</param>
        /// <typeparam name="TInput">The input type parameter.</typeparam>
        /// <typeparam name="TOutput">The output type parameter.</typeparam>
        private static Task Worker <TInput, TOutput>(Func <TInput, TOutput> method)
        {
            return(AutomationExtensions.RunTask(
                       new {
                input = ChannelMarker.ForRead <TInput>(WORKERINPUT),
                output = ChannelMarker.ForWrite <TOutput>(WORKEROUTPUT)
            },

                       async self => {
                try
                {
                    while (true)
                    {
                        await self.output.WriteAsync(method(await self.input.ReadAsync().ConfigureAwait(false))).ConfigureAwait(false);
                    }
                }
                catch (Exception ex)
                {
                    if (!(ex is RetiredException))
                    {
                        Console.WriteLine("ex: {0}", ex);
                    }
                    throw;
                }
            }
                       ));
        }
Пример #2
0
        public void TestRetireWithoutLoss()
        {
            Task[] tasks;
            int    count = 0;

            using (new ChannelScope())
            {
                tasks = new Task[] {
                    AutomationExtensions.RunTask(
                        new { channel = ChannelMarker.ForWrite <int>(CHANNEL_NAME) },

                        async self =>
                    {
                        await Task.Delay(500);
                        await self.channel.WriteAsync(1);
                    }
                        ),

                    AutomationExtensions.RunTask(
                        new { channel = ChannelMarker.ForWrite <int>(CHANNEL_NAME) },

                        async self =>
                    {
                        await Task.Delay(1000);
                        await self.channel.WriteAsync(1);
                    }
                        ),

                    AutomationExtensions.RunTask(
                        new { channel = ChannelMarker.ForRead <int>(CHANNEL_NAME) },

                        async self =>
                    {
                        while (true)
                        {
                            await self.channel.ReadAsync();
                            count++;
                        }
                    }
                        )
                };
            }

            var all = Task.WhenAll(tasks).WaitForTask();

            if (count != 2)
            {
                throw new Exception(string.Format("Unexpected count, expected {0} but got {1}", 2, count));
            }
            if (all.IsFaulted || !all.IsCompleted)
            {
                throw new Exception("Unexpected task state");
            }
        }
Пример #3
0
 /// <summary>
 /// Emits all values from the enumerable into the network
 /// </summary>
 /// <param name="values">Values.</param>
 /// <typeparam name="TInput">The 1st type parameter.</typeparam>
 private static Task Generator <TInput>(IEnumerable <TInput> values)
 {
     return(AutomationExtensions.RunTask(
                new { channel = ChannelMarker.ForWrite <TInput>(WORKERINPUT) },
                async self => {
         foreach (var value in values)
         {
             await self.channel.WriteAsync(value).ConfigureAwait(false);
         }
     }
                ));
 }
Пример #4
0
        private void TestReaderOverflow(QueueOverflowStrategy strategy)
        {
            using (new IsolatedChannelScope())
            {
                var readertasks = Enumerable.Range(0, 4).Select(count =>
                                                                AutomationExtensions.RunTask(new {
                    Input = ChannelMarker.ForRead <int>("channel", maxPendingReaders: 3, pendingReadersOverflowStrategy: strategy)
                },
                                                                                             async x =>
                {
                    //Console.WriteLine("Started {0}", count);

                    while (true)
                    {
                        await x.Input.ReadAsync();
                    }
                })
                                                                ).ToList();

                using (ChannelManager.GetChannel <int>("channel").AsWriteOnly())
                    Task.Delay(500).WaitForTaskOrThrow();
                Task.WhenAny(readertasks.Union(new [] { Task.Delay(1000) })).WaitForTaskOrThrow();
                Task.Delay(500).WaitForTaskOrThrow();

                int discard;
                switch (strategy)
                {
                case QueueOverflowStrategy.FIFO:
                    discard = 0;
                    break;

                case QueueOverflowStrategy.LIFO:
                    discard = readertasks.Count - 2;
                    break;

                case QueueOverflowStrategy.Reject:
                default:
                    discard = readertasks.Count - 1;
                    break;
                }

                Assert.IsTrue(readertasks[discard].IsFaulted);
                TestAssert.IsInstanceOf <ChannelOverflowException>(readertasks[discard].Exception.Flatten().InnerExceptions.First());

                readertasks.RemoveAt(discard);

                Assert.IsTrue(readertasks.All(x => x.IsCompleted && !x.IsFaulted && !x.IsCanceled));
            }
        }
Пример #5
0
        /// <summary>
        /// Collects input and combines it with the join method
        /// </summary>
        /// <param name="joinmethod">The method used to join results.</param>
        /// <param name="initial">The initial input to the join method, aka. the neutral element.</param>
        /// <typeparam name="TOutput">The type parameter for the data to join.</typeparam>
        /// <typeparam name="TResult">The type parameter for the aggregated data.</typeparam>
        private static async Task <TResult> Collector <TOutput, TResult>(Func <TResult, TOutput, TResult> joinmethod, TResult initial)
        {
            var current = initial;

            await AutomationExtensions.RunTask(
                new { channel = ChannelMarker.ForRead <TOutput>(WORKEROUTPUT) },
                async self => {
                while (true)
                {
                    current = joinmethod(current, await self.channel.ReadAsync().ConfigureAwait(false));
                }
            }
                ).ConfigureAwait(false);

            return(current);
        }
Пример #6
0
        public void TestScope()
        {
            var values      = new[] { 0, 1, 2, 3, 4 };
            var counter     = new CounterShim();
            var readercount = 10;
            var name        = "bcast";

            using (new IsolatedChannelScope())
            {
                var writer = AutomationExtensions.RunTask(
                    new { chan = ChannelMarker.ForWrite <int>(name, broadcast: true, initialBroadcastBarrier: readercount) },
                    async self =>
                {
                    foreach (var v in values)
                    {
                        await self.chan.WriteAsync(v);
                    }
                }
                    );

                var readers = Enumerable.Range(0, readercount).Select(x => AutomationExtensions.RunTask(
                                                                          new { chan = ChannelMarker.ForRead <int>(name) },
                                                                          async self =>
                {
                    foreach (var v in values)
                    {
                        var r = await self.chan.ReadAsync();
                        counter.Increment();
                        if (Comparer <int> .Default.Compare(v, r) != 0)
                        {
                            throw new Exception(string.Format("Got {0} but expected {1}", r, v));
                        }
                    }
                }
                                                                          )).ToArray();

                Task.WhenAll(readers.Union(new[] { writer })).WaitForTaskOrThrow();
                if (counter.Count != readercount * values.Length)
                {
                    throw new Exception(string.Format("The counter said {0} values were read, but {1} was expected", counter.Count, readercount * values.Length));
                }
            }
        }
Пример #7
0
        private void TestCappedPool(int poolsize, int readers, int writes)
        {
            var concurrent     = 0;
            var max_concurrent = 0;
            var rnd            = new Random();
            var earlyRetire    = new TaskCompletionSource <bool>();

            using (new IsolatedChannelScope())
                using (new ExecutionScope(poolsize <= 0 ? ThreadPool.DEFAULT_THREADPOOL : new CappedThreadedThreadPool(poolsize)))
                {
                    var readertasks = Task.WhenAll(Enumerable.Range(0, readers).Select(count =>
                                                                                       AutomationExtensions.RunTask(new {
                        Input = ChannelMarker.ForRead <int>("channel")
                    },
                                                                                                                    async x =>
                    {
                        //Console.WriteLine("Started {0}", count);

                        while (true)
                        {
                            await x.Input.ReadAsync();
                            var cur = System.Threading.Interlocked.Increment(ref concurrent);
                            //Console.WriteLine("Active {0}", count);

                            // Dirty access to "concurrent" and "max_concurrent" variables
                            max_concurrent = Math.Max(cur, Math.Max(max_concurrent, concurrent));

                            if (cur > poolsize && poolsize > 0)
                            {
                                Console.WriteLine("Found {0} concurrent threads", cur);
                                earlyRetire.TrySetException(new Exception(string.Format("Found {0} concurrent threads", cur)));
                                throw new Exception(string.Format("Found {0} concurrent threads", cur));
                            }

                            // By blocking the actual thread, we provoke the threadpool to start multiple threads
                            System.Threading.Thread.Sleep(rnd.Next(10, 500));

                            // Dirty access to "concurrent" and "max_concurrent" variables
                            max_concurrent = Math.Max(cur, Math.Max(max_concurrent, concurrent));
                            System.Threading.Interlocked.Decrement(ref concurrent);
                            //Console.WriteLine("Inactive {0}", count);
                        }
                    })
                                                                                       ));

                    var writetask = AutomationExtensions.RunTask(new {
                        Output = ChannelMarker.ForWrite <int>("channel")
                    },
                                                                 async x => {
                        foreach (var i in Enumerable.Range(0, writes))
                        {
                            //Console.WriteLine("Writing {0}", i);
                            await x.Output.WriteAsync(i);
                        }
                    });

                    var timeout = Task.Delay((writes * 500) + 5000);
                    if (Task.WhenAny(Task.WhenAll(readertasks, writetask), timeout, earlyRetire.Task).WaitForTaskOrThrow() == timeout)
                    {
                        throw new TimeoutException("I've waited for so long ....");
                    }

                    Console.WriteLine("Threads at shutdown: {0}", concurrent);

                    ExecutionScope.Current.EnsureFinishedAsync(TimeSpan.FromSeconds(5)).WaitForTaskOrThrow();
                    Console.WriteLine("Max concurrent threads: {0}, should be {1}", max_concurrent, poolsize <= 0 ? "unlimited" : poolsize.ToString());
                }
        }