예제 #1
0
        public void Send_CancellationToken_ShouldThrow()
        {
            channel <int>           sut       = new channel <int>(2);
            Exception               exception = null;
            CancellationTokenSource cts       = new CancellationTokenSource();
            Task producer = Task.Run(() =>
            {
                sut.Send(1);
                sut.Send(2);
                try
                {
                    sut.Send(3, cts.Token);
                }
                catch (Exception ex)
                {
                    exception = ex;
                }
            });

            producer.Wait(m_awaitTimeout);
            cts.Cancel();
            producer.Wait(); // Await the catch block to finish

            Assert.AreEqual(2, sut.Length);
            Assert.IsInstanceOfType(exception, typeof(OperationCanceledException));
        }
예제 #2
0
        public void ProducerConsumer_FastProducer_SlowConsumer()
        {
            channel <int> sut            = new channel <int>(2);
            bool          producerCalled = false;
            Task          producer       = Task.Run(() =>
            {
                sut.Send(1);
                sut.Send(2);
                sut.Send(3);
                producerCalled = true;
            });

            bool       consumerCalled = false;
            List <int> items          = new List <int>();
            Task       consumer       = Task.Run(async() =>
            {
                await Task.Delay(m_slowActionLatency);
                items.Add(sut.Receive());
                await Task.Delay(m_slowActionLatency);
                items.Add(sut.Receive());
                await Task.Delay(m_slowActionLatency);
                items.Add(sut.Receive());
                consumerCalled = true;
            });

            Task.WaitAll(producer, consumer);

            Assert.AreEqual(0, sut.Length);
            Assert.IsTrue(producerCalled);
            Assert.IsTrue(consumerCalled);
            CollectionAssert.AreEquivalent(new[] { 1, 2, 3 }, items.ToArray());
        }
예제 #3
0
        public void Yield_ClosedChan_ShouldNotBeBlocked()
        {
            channel <int> sut      = new channel <int>(2);
            Task          producer = Task.Run(() =>
            {
                sut.Send(1);
                sut.Send(2);
                sut.Send(3);
            });

            List <int> items    = new List <int>();
            bool       called   = false;
            Task       consumer = Task.Run(() =>
            {
                foreach (int i in sut)
                {
                    items.Add(i);
                }
                called = true;
            });

            producer.Wait();
            sut.Close();
            consumer.Wait(m_awaitTimeout);

            Assert.AreEqual(3, items.Count);
            Assert.IsTrue(called);
        }
예제 #4
0
        public void Receive_FromNonEmptyChan_ShouldNotBeBlocked()
        {
            channel <int> sut = new channel <int>(2);

            sut.Send(1);
            sut.Send(2);

            int item1 = sut.Receive();
            int item2 = sut.Receive();

            Assert.AreEqual(0, sut.Length);
            Assert.AreEqual(1, item1);
            Assert.AreEqual(2, item2);
        }
예제 #5
0
        public void ProducerConsumer_MoreThanChanSize()
        {
            channel <int> sut            = new channel <int>(2);
            bool          producerCalled = false;
            int           totalItemCount = 100;
            Task          producer       = Task.Run(() =>
            {
                for (int i = 1; i <= totalItemCount; i++)
                {
                    sut.Send(i);
                }
                producerCalled = true;
            });

            bool       consumerCalled = false;
            List <int> items          = new List <int>();
            Task       consumer       = Task.Run(() =>
            {
                for (int i = 1; i <= totalItemCount; i++)
                {
                    items.Add(sut.Receive());
                }
                consumerCalled = true;
            });

            Task.WaitAll(producer, consumer);

            Assert.AreEqual(0, sut.Length);
            Assert.IsTrue(producerCalled);
            Assert.IsTrue(consumerCalled);
            CollectionAssert.AreEquivalent(Enumerable.Range(1, totalItemCount).ToArray(), items.ToArray());
        }
예제 #6
0
        public void Send_MoreThanSize_SendShouldBeBlocked()
        {
            channel <int> sut      = new channel <int>(2);
            bool          called   = false;
            Task          producer = Task.Run(() =>
            {
                sut.Send(1);
                sut.Send(2);
                sut.Send(3);
                called = true;
            });

            producer.Wait(m_awaitTimeout);

            Assert.AreEqual(2, sut.Length);
            Assert.IsFalse(called);
        }
예제 #7
0
        public void Send_LessThanSize_SendShouldNotBeBlocked()
        {
            channel <int> sut    = new channel <int>(2);
            bool          called = false;

            Task producer = Task.Run(() =>
            {
                sut.Send(1);
                sut.Send(2);
                called = true;
            });

            producer.Wait();

            Assert.AreEqual(2, sut.Length);
            Assert.IsTrue(called);
        }
예제 #8
0
    static void sum(slice <int> s, ref channel <int> c)
    {
        var sum = 0;

        foreach ((long, int)_tuple in s)
        {
            var(_, v) = _tuple;
            sum      += v;
        }
        c.Send(sum); // send sum to c
    }
예제 #9
0
        public void SendMany_ReceiveFew_SendShouldBeBlocked()
        {
            channel <int> sut      = new channel <int>(2);
            bool?         called   = null;
            Task          producer = Task.Run(() =>
            {
                sut.Send(1);
                sut.Send(2);
                sut.Send(3);
                sut.Send(4);
                sut.Send(5);
                called = false;
                sut.Send(6);
                called = true;
            });

            List <int> items = new List <int> {
                sut.Receive(), sut.Receive(), sut.Receive()
            };

            producer.Wait(m_awaitTimeout);

            Assert.AreEqual(2, sut.Length);
            Assert.IsFalse(called.GetValueOrDefault());
            CollectionAssert.AreEquivalent(new[] { 1, 2, 3 }, items.ToArray());
        }
예제 #10
0
    static void fibonacci(int n, channel <int> c)
    {
        int x = 0, y = 1;

        for (int i = 0; i < n; i++)
        {
            c.Send(x);
            var _y1 = x + y;
            x = y;
            y = _y1;
        }
        close(c);
    }
예제 #11
0
        public void Send_AfterClosed_ShouldThrow()
        {
            channel <int> sut = new channel <int>(2);

            sut.Send(1);
            sut.Close();

            Exception exception = null;

            try
            {
                sut.Send(2);
            }
            catch (Exception ex)
            {
                exception = ex;
            }

            Assert.AreEqual(1, sut.Length);
            Assert.IsTrue(sut.IsClosed);
            Assert.IsInstanceOfType(exception, typeof(PanicException));
        }
예제 #12
0
        public void Receive_RaceCondition_OnlyOneCanGetTheSentItemEachTime()
        {
            channel <int>       chan  = new channel <int>(1);
            ConcurrentBag <int> items = new ConcurrentBag <int>();
            Task receiver1            = Task.Run(() => items.Add(chan.Receive()));
            Task receiver2            = Task.Run(() => items.Add(chan.Receive()));
            Task receiver3            = Task.Run(() => items.Add(chan.Receive()));

            Thread.Sleep(m_slowActionLatency);
            chan.Send(1);

            Task.WaitAll(new[] { receiver1, receiver2, receiver3 }, m_awaitTimeout);

            CollectionAssert.AreEquivalent(new[] { 1 }, items.ToArray());
        }
예제 #13
0
        public void SendFew_ReceiveMany_ReceiveShouldBeBlocked()
        {
            channel <int> sut = new channel <int>(2);

            sut.Send(1);
            sut.Send(2);

            bool?      called   = null;
            List <int> items    = new List <int>();
            Task       consumer = Task.Run(() =>
            {
                items.Add(sut.Receive());
                items.Add(sut.Receive());
                called = false;
                items.Add(sut.Receive());
                called = true;
            });

            consumer.Wait(m_awaitTimeout);

            Assert.AreEqual(0, sut.Length);
            Assert.IsFalse(called.GetValueOrDefault());
            CollectionAssert.AreEquivalent(new[] { 1, 2 }, items.ToArray());
        }
예제 #14
0
        public void Receive_ShouldGetTheSameObjectThatSenderSent()
        {
            channel <object> chan = new channel <object>(1);
            object           item = new object();

            Task receiver = Task.Run(() =>
            {
                Thread.Sleep(m_slowActionLatency);
                chan.Send(item);
            });

            object result = chan.Receive();

            receiver.Wait();

            Assert.AreSame(item, result);
        }
예제 #15
0
        public void Receive_RaceCondition_OneItemIsReceivedOnlyOnce()
        {
            channel <int>       chan  = new channel <int>(1);
            ConcurrentBag <int> items = new ConcurrentBag <int>();

            int[]  samples   = Enumerable.Range(0, 3).ToArray();
            Task[] receivers = samples.Select(i => { return(Task.Run(() => items.Add(chan.Receive()))); }).ToArray();

            Thread.Sleep((int)m_slowActionLatency.TotalMilliseconds);
            foreach (int i in samples)
            {
                chan.Send(i);
            }

            Task.WaitAll(receivers);

            CollectionAssert.AreEquivalent(samples, items.ToArray());
        }
예제 #16
0
        public void Receive_ShouldNotBeBlocked_OnceOneSend()
        {
            channel <int> chan     = new channel <int>(1);
            bool          called   = false;
            int           item     = 0;
            Task          receiver = Task.Run(() =>
            {
                item   = chan.Receive();
                called = true;
            });

            Thread.Sleep(m_slowActionLatency);
            chan.Send(1); // Make sure Receive() is called before Send()

            receiver.Wait();

            Assert.AreEqual(1, item);
            Assert.IsTrue(called);
        }
예제 #17
0
        public void ProducerConsumer_MultipleProducers_MultipleConsumers()
        {
            channel <int> sut             = new channel <int>(2);
            bool          producer1Called = false;
            Task          producer1       = Task.Run(() =>
            {
                sut.Send(1);
                sut.Send(2);
                sut.Send(3);
                producer1Called = true;
            });

            bool producer2Called = false;
            Task producer2       = Task.Run(() =>
            {
                sut.Send(4);
                sut.Send(5);
                sut.Send(6);
                producer2Called = true;
            });

            ConcurrentBag <int> items = new ConcurrentBag <int>();
            bool consumer1Called      = false;
            Task consumer1            = Task.Run(() =>
            {
                items.Add(sut.Receive());
                items.Add(sut.Receive());
                items.Add(sut.Receive());
                consumer1Called = true;
            });

            bool consumer2Called = false;
            Task consumer2       = Task.Run(() =>
            {
                items.Add(sut.Receive());
                items.Add(sut.Receive());
                items.Add(sut.Receive());
                consumer2Called = true;
            });

            Task.WaitAll(producer1, producer2, consumer1, consumer2);

            Assert.AreEqual(0, sut.Length);
            Assert.IsTrue(producer1Called);
            Assert.IsTrue(producer2Called);
            Assert.IsTrue(consumer1Called);
            Assert.IsTrue(consumer2Called);
            CollectionAssert.AreEquivalent(new[] { 1, 2, 3, 4, 5, 6 }, items.ToArray());
        }