示例#1
0
        public void Run()
        {
            // The following basic example demonstrates a case in which
            // a JoinBlock<T1,T2,T3> object requires multiple data to compute
            // a value. This example creates a JoinBlock<T1,T2,T3> object
            // that requires two Int32 values and a Char value to perform
            // an arithmetic operation.

            // Create a JoinBlock<int, int, char> object that requires
            // two numbers and an operator.
            var joinBlock = new JoinBlock <int, int, char>();

            // Post two values to each target of the join.

            joinBlock.Target1.Post(3);
            joinBlock.Target1.Post(6);

            joinBlock.Target2.Post(5);
            joinBlock.Target2.Post(4);

            joinBlock.Target3.Post('+');
            joinBlock.Target3.Post('-');

            // Receive each group of values and apply the operator part
            // to the number parts.

            for (int i = 0; i < 2; i++)
            {
                var data = joinBlock.Receive();
                switch (data.Item3)
                {
                case '+':
                    Console.WriteLine("{0} + {1} = {2}",
                                      data.Item1, data.Item2, data.Item1 + data.Item2);
                    break;

                case '-':
                    Console.WriteLine("{0} - {1} = {2}",
                                      data.Item1, data.Item2, data.Item1 - data.Item2);
                    break;

                default:
                    Console.WriteLine("Unknown operator '{0}'.", data.Item3);
                    break;
                }
            }

            /* Output:
             * 3 + 5 = 8
             * 6 - 4 = 2
             */
        }
示例#2
0
        static void ShowJoinBlock()
        {
            // <snippet8>
            // Create a JoinBlock<int, int, char> object that requires
            // two numbers and an operator.
            var joinBlock = new JoinBlock <int, int, char>();

            // Post two values to each target of the join.

            joinBlock.Target1.Post(3);
            joinBlock.Target1.Post(6);

            joinBlock.Target2.Post(5);
            joinBlock.Target2.Post(4);

            joinBlock.Target3.Post('+');
            joinBlock.Target3.Post('-');

            // Receive each group of values and apply the operator part
            // to the number parts.

            for (int i = 0; i < 2; i++)
            {
                var data = joinBlock.Receive();
                switch (data.Item3)
                {
                case '+':
                    Console.WriteLine("{0} + {1} = {2}",
                                      data.Item1, data.Item2, data.Item1 + data.Item2);
                    break;

                case '-':
                    Console.WriteLine("{0} - {1} = {2}",
                                      data.Item1, data.Item2, data.Item1 - data.Item2);
                    break;

                default:
                    Console.WriteLine("Unknown operator '{0}'.", data.Item3);
                    break;
                }
            }

            /* Output:
             * 3 + 5 = 8
             * 6 - 4 = 2
             */
            // </snippet8>
        }
示例#3
0
        static public void Run()
        {
            var opts = new GroupingDataflowBlockOptions {
                Greedy = false
            };
            var jBlock = new JoinBlock <int, int>(opts);

            for (int i = 0; i < 10; i++)
            {
                Task <bool> task = jBlock.Target1.SendAsync(i);
                // needed to capture 'i' so we can use it in `ContinueWith`
                int iCopy = i;
                task.ContinueWith(t => {
                    if (t.Result)
                    {
                        Console.WriteLine("Target1 accepted: " + iCopy);
                    }
                    else
                    {
                        Console.WriteLine("Target1 REFUSED: " + iCopy);
                    }
                });
            }

            for (int i = 0; i < 10; i++)
            {
                Task <bool> task = jBlock.Target2.SendAsync(i);
                // needed to capture 'i' so we can use it in `ContinueWith`
                int iCopy = i;
                task.ContinueWith(t => {
                    if (t.Result)
                    {
                        Console.WriteLine("Target2 accepted: " + iCopy);
                    }
                    else
                    {
                        Console.WriteLine("Target2 REFUSED: " + iCopy);
                    }
                });
            }

            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(jBlock.Receive());
            }

            Console.WriteLine("Done");
        }
示例#4
0
        public UserModel Crete(int id, string name)
        {
            var jb = new JoinBlock <int, string>();

            jb.Target1.Post(id);
            jb.Target2.Post(name);


            var result = jb.Receive();
            var res    = new UserModel {
                Id   = result.Item1,
                Name = result.Item2
            };

            return(res);
        }
示例#5
0
        public void BoundedCapacityTest()
        {
            var block = new JoinBlock <int, int> (
                new GroupingDataflowBlockOptions {
                BoundedCapacity = 1
            });

            Assert.IsTrue(block.Target1.Post(1));
            Assert.IsFalse(block.Target1.Post(2));

            Assert.IsTrue(block.Target2.Post(10));
            Assert.IsFalse(block.Target2.Post(11));
            Assert.IsFalse(block.Target1.Post(3));

            Assert.AreEqual(Tuple.Create(1, 10), block.Receive());
            Assert.IsTrue(block.Target1.Post(4));
        }
        static public void Run()
        {
            var jBlock = new JoinBlock <int, int>();

            for (int i = 0; i < 10; i++)
            {
                jBlock.Target1.Post(i);
            }

            for (int i = -9; i < 1; i++)
            {
                jBlock.Target2.Post(i);
            }

            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(jBlock.Receive());
            }

            Console.WriteLine("Done");
        }
示例#7
0
        /// <summary>
        /// The following basic example demonstrates a case in which a JoinBlock<T1,T2,T3>
        /// object requires multiple data to compute a value. This example creates a
        /// JoinBlock<T1,T2,T3> object that requires two Int32 values and a Char value to
        /// perform an arithmetic operation.
        /// </summary>
        public static void Run()
        {
            // Create a JoinBlock<int, int, char> object that requires
            // two numbers and an operator.

            /*Provides a dataflow block that joins across multiple dataflow sources,
             * which are not necessarily of the same type, waiting for one item to arrive for each type before
             * they’re all released together as a tuple that contains one item per type*/
            JoinBlock <int, int, char> joinBlock = new JoinBlock <int, int, char>();

            // Post two values to each target of the join.
            joinBlock.Target1.Post(3);
            joinBlock.Target1.Post(6);

            joinBlock.Target2.Post(5);
            joinBlock.Target2.Post(4);

            joinBlock.Target3.Post('+');
            joinBlock.Target3.Post('-');

            // Receive each group of values and apply the operator part
            // to the number parts.
            for (int i = 0; i < 2; i++)
            {
                Tuple <int, int, char> data = joinBlock.Receive();
                switch (data.Item3)
                {
                case '+':
                    Console.WriteLine("{0} + {1} = {2}", data.Item1, data.Item2, data.Item1 + data.Item2);
                    break;

                case '-':
                    Console.WriteLine("{0} - {1} = {2}", data.Item1, data.Item2, data.Item1 - data.Item2);
                    break;

                default:
                    Console.WriteLine("Unknown operator '{0}'.", data.Item3); break;
                }
            }
        }
示例#8
0
        public override void Run()
        {
            // 只可以传入两个或三个泛型类型
            JoinBlock <RunModel, string, RunModel> joinBlock = new JoinBlock <RunModel, string, RunModel>();
            var models = this.CreateCollection(2);

            // 注意:并发操作下,必须 lock,否则组内的数据可能因为顺序而匹配为错误的组
            joinBlock.Target1.Post(models[0]);
            joinBlock.Target2.Post("next is");
            joinBlock.Target3.Post(models[1]);

            joinBlock.Target1.Post(models[1]);
            joinBlock.Target2.Post("last is");
            joinBlock.Target3.Post(models[0]);

            // JoinBlock 每个 Target 的数据必须匹配为完整组时才可以触发处理逻辑
            for (int index = 0; index < 2; index++)
            {
                var result = joinBlock.Receive();
                Helper.PrintLine($"{result.Item1.Name} {result.Item2} {result.Item3}");
            }
        }
        static public void Run()
        {
            var opts = new GroupingDataflowBlockOptions {
                Greedy = false
            };
            var jBlock = new JoinBlock <int, int>(opts);

            for (int i = 0; i < 10; i++)
            {
                if (jBlock.Target1.Post(i))
                {
                    Console.WriteLine("Target1 accepted: " + i);
                }
                else
                {
                    Console.WriteLine("Target1 REFUSED: " + i);
                }
            }

            for (int i = 0; i < 10; i++)
            {
                if (jBlock.Target2.Post(i))
                {
                    Console.WriteLine("Target2 accepted: " + i);
                }
                else
                {
                    Console.WriteLine("Target2 REFUSED: " + i);
                }
            }

            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(jBlock.Receive());
            }

            Console.WriteLine("Done");
        }
        public async Task TestLinkTo_DoubleLinking()
        {
            foreach (bool greedy in DataflowTestHelpers.BooleanValues)
            foreach (bool append in DataflowTestHelpers.BooleanValues)
            {
                var source1 = new BufferBlock<int>();
                var source2 = new BufferBlock<int>();
                var jb = new JoinBlock<int, int>(new GroupingDataflowBlockOptions { MaxNumberOfGroups = 1, Greedy = greedy });

                var ignored = source1.Completion.ContinueWith(_ => jb.Target1.Complete(), TaskScheduler.Default);
                ignored = source2.Completion.ContinueWith(_ => jb.Target2.Complete(), TaskScheduler.Default);

                using (source1.LinkTo(jb.Target1))
                {
                    source1.LinkTo(jb.Target1, new DataflowLinkOptions { Append = append }); // force NopLinkPropagator creation
                }
                using (source2.LinkTo(jb.Target2))
                {
                    source2.LinkTo(jb.Target2, new DataflowLinkOptions { Append = append }); // force NopLinkPropagator creation
                }

                source1.Post(42);
                source2.Post(43);

                source1.Complete();
                source2.Complete();

                var tuple = jb.Receive();
                Assert.Equal(expected: 42, actual: tuple.Item1);
                Assert.Equal(expected: 43, actual: tuple.Item2);
            }

            ITargetBlock<int> target = new ActionBlock<int>(i => { });
            ISourceBlock<int> source = new BufferBlock<int>();
            using (source.LinkTo(target))
            {
                source.LinkTo(target, new DataflowLinkOptions { PropagateCompletion = true });
                source.LinkTo(target, new DataflowLinkOptions { PropagateCompletion = true }, f => false);
            }
            source.Fault(new FormatException());
            await Assert.ThrowsAsync<AggregateException>(() => target.Completion);
        }
        public void TestLinkTo_TwoPhaseCommit()
        {
            var source1 = new BufferBlock<int>();
            var source2 = new BufferBlock<int>();
            var jb = new JoinBlock<int, int>(new GroupingDataflowBlockOptions { Greedy = false, MaxNumberOfGroups = 1 });

            source1.Completion.ContinueWith(_ => jb.Target1.Complete(), TaskScheduler.Default);
            source2.Completion.ContinueWith(_ => jb.Target2.Complete(), TaskScheduler.Default);

            source1.LinkTo(jb.Target1);
            source2.LinkTo(jb.Target2);

            source1.Post(42);
            source2.Post(43);

            source1.Complete();
            source2.Complete();

            var tuple = jb.Receive();
            Assert.Equal(expected: 42, actual: tuple.Item1);
            Assert.Equal(expected: 43, actual: tuple.Item2);
        }
示例#12
0
		public void BoundedCapacityTest ()
		{
			var block = new JoinBlock<int, int> (
				new GroupingDataflowBlockOptions { BoundedCapacity = 1 });
			Assert.IsTrue (block.Target1.Post (1));
			Assert.IsFalse (block.Target1.Post (2));

			Assert.IsTrue (block.Target2.Post (10));
			Assert.IsFalse (block.Target2.Post (11));
			Assert.IsFalse (block.Target1.Post (3));

			Assert.AreEqual (Tuple.Create (1, 10), block.Receive ());
			Assert.IsTrue (block.Target1.Post (4));
		}
示例#13
0
        public void RunJoinBlockConformanceTests()
        {
            // Test Post/Receive single block
            {
                int iter = 2;

                var block2 = new JoinBlock <int, int>();
                for (int i = 0; i < iter; i++)
                {
                    block2.Target1.Post(i);
                    block2.Target2.Post(i);
                    var msg = block2.Receive();

                    Assert.False(msg.Item1 != i || msg.Item2 != i, string.Format("JoinBlock Post/Receive failed expected {0},{1} and actual {2},{3}", i, i, msg.Item1, msg.Item2));
                }

                var block3 = new JoinBlock <int, int, int>();
                for (int i = 0; i < iter; i++)
                {
                    block3.Target1.Post(i);
                    block3.Target2.Post(i);
                    block3.Target3.Post(i);
                    var msg = block3.Receive();
                    Assert.False(msg.Item1 != i || msg.Item2 != i || msg.Item3 != i, string.Format("JoinBlock Post/Receive failed expected {0},{1},{2} and actual {3},{4},{5}", i, i, i, msg.Item1, msg.Item2, msg.Item3));
                }
            }

            // Test PostAll then Receive single block
            {
                int iter = 2;

                var block2 = new JoinBlock <int, int>();
                for (int i = 0; i < iter; i++)
                {
                    block2.Target1.Post(i);
                    block2.Target2.Post(i);
                }
                for (int i = 0; i < iter; i++)
                {
                    var msg = block2.Receive();
                    Assert.False(msg.Item1 != msg.Item2, "JoinBlock PostAll then Receive failed expected, incorrect msg pair");
                }

                var block3 = new JoinBlock <int, int, int>();
                for (int i = 0; i < iter; i++)
                {
                    block3.Target1.Post(i);
                    block3.Target2.Post(i);
                    block3.Target3.Post(i);
                }
                for (int i = 0; i < iter; i++)
                {
                    var msg = block3.Receive();
                    Assert.False(msg.Item1 != msg.Item2 || msg.Item2 != msg.Item3, "JoinBlock PostAll then Receive failed expected, incorrect msg pair");
                }
            }

            //Test one target Post with TryReceive
            {
                var block2 = new JoinBlock <int, int>();
                block2.Target1.Post(0);
                Tuple <int, int> result2;
                Assert.False(block2.TryReceive(out result2), "JoinBlock.TryReceive failed, returned true and only one target posted a message");
                Assert.False(block2.OutputCount > 0, "JoinBlock.OutputCount failed, returned count > 0 and only one target posted a message");
                var block3 = new JoinBlock <int, int, int>();
                block3.Target1.Post(0);
                Tuple <int, int, int> result3;
                Assert.False(block3.TryReceive(out result3), "JoinBlock.TryReceive failed, returned true and only one target posted a message");
                Assert.False(block3.OutputCount > 0, "JoinBlock.OutputCount failed, returned count > 0 and only one target posted a message");
            }

            // Test JoinBlock`2 using a precanceled token
            {
                var localPassed = true;
                try
                {
                    var cts = new CancellationTokenSource();
                    cts.Cancel();
                    var dbo = new GroupingDataflowBlockOptions {
                        CancellationToken = cts.Token, MaxNumberOfGroups = 1
                    };
                    var jb = new JoinBlock <int, int>(dbo);

                    Tuple <int, int>          ignoredValue;
                    IList <Tuple <int, int> > ignoredValues;
                    localPassed &= jb.LinkTo(new ActionBlock <Tuple <int, int> >(delegate { })) != null;
                    localPassed &= jb.Target1.Post(42) == false;
                    localPassed &= jb.Target2.Post(42) == false;
                    localPassed &= jb.Target1.SendAsync(42).Result == false;
                    localPassed &= jb.Target2.SendAsync(42).Result == false;
                    localPassed &= jb.TryReceiveAll(out ignoredValues) == false;
                    localPassed &= jb.TryReceive(out ignoredValue) == false;
                    localPassed &= jb.OutputCount == 0;
                    localPassed &= jb.Completion != null;
                    jb.Target1.Complete();
                    jb.Target2.Complete();
                }
                catch (Exception)
                {
                    localPassed = false;
                }

                Assert.True(localPassed, string.Format("Precanceled tokens on JB`2 - {0}", localPassed ? "Passed" : "FAILED"));
            }

            // Test JoinBlock`3 using a precanceled token
            {
                var localPassed = true;
                try
                {
                    var cts = new CancellationTokenSource();
                    cts.Cancel();
                    var dbo = new GroupingDataflowBlockOptions {
                        CancellationToken = cts.Token, MaxNumberOfGroups = 1
                    };
                    var jb = new JoinBlock <int, int, int>(dbo);

                    Tuple <int, int, int>          ignoredValue;
                    IList <Tuple <int, int, int> > ignoredValues;
                    localPassed &= jb.LinkTo(new ActionBlock <Tuple <int, int, int> >(delegate { })) != null;
                    localPassed &= jb.Target1.Post(42) == false;
                    localPassed &= jb.Target2.Post(42) == false;
                    localPassed &= jb.Target3.Post(42) == false;
                    localPassed &= jb.Target1.SendAsync(42).Result == false;
                    localPassed &= jb.Target2.SendAsync(42).Result == false;
                    localPassed &= jb.Target3.SendAsync(42).Result == false;
                    localPassed &= jb.TryReceiveAll(out ignoredValues) == false;
                    localPassed &= jb.TryReceive(out ignoredValue) == false;
                    localPassed &= jb.OutputCount == 0;
                    localPassed &= jb.Completion != null;
                    jb.Target1.Complete();
                    jb.Target2.Complete();
                    jb.Target3.Complete();
                }
                catch (Exception)
                {
                    localPassed = false;
                }

                Assert.True(localPassed, string.Format("Precanceled tokens on JB`3 - {0}", localPassed ? "Passed" : "FAILED"));
            }

            // Test JoinBlock`2 completion through all targets
            {
                var localPassed = true;
                var join        = new JoinBlock <int, int>();
                join.Target1.Post(1);
                join.Target1.Complete();
                join.Target2.Complete();
                localPassed = join.Completion.Wait(2000);

                Assert.True(localPassed, string.Format("JoinBlock`2 completed through targets - {0}", localPassed ? "Passed" : "FAILED"));
            }

            // Test JoinBlock`3 completion through all targets
            {
                var localPassed = true;
                var join        = new JoinBlock <int, int, int>();
                join.Target1.Post(1);
                join.Target1.Complete();
                join.Target2.Complete();
                join.Target3.Complete();
                localPassed = join.Completion.Wait(2000);

                Assert.True(localPassed, string.Format("JoinBlock`3 completed through targets - {0}", localPassed ? "Passed" : "FAILED"));
            }

            // Test JoinBlock`2 completion through block
            {
                var localPassed = true;
                var join        = new JoinBlock <int, int>();
                join.Target1.Post(1);
                join.Complete();
                localPassed = join.Completion.Wait(2000);

                Assert.True(localPassed, string.Format("JoinBlock`2 completed through block - {0}", localPassed ? "Passed" : "FAILED"));
            }

            // Test JoinBlock`3 completion through block
            {
                var localPassed = true;
                var join        = new JoinBlock <int, int, int>();
                join.Target1.Post(1);
                join.Complete();
                localPassed = join.Completion.Wait(2000);

                Assert.True(localPassed, string.Format("JoinBlock`3 completed through block - {0}", localPassed ? "Passed" : "FAILED"));
            }
        }
示例#14
0
        private static void T2()
        {
            Console.ReadKey();

            var rnd = new Random();
            var executionDataflowBlockOptions = new ExecutionDataflowBlockOptions()
            {
                MaxDegreeOfParallelism = 10
            };
            ActionBlock <int> action1 = new ActionBlock <int>(async(x) =>
            {
                var millisecondsDelay = rnd.Next(10, 2000);
                await Task.Delay(millisecondsDelay);
                Console.WriteLine("Block1: " + x);
            }, executionDataflowBlockOptions);

            ActionBlock <int> action2 = new ActionBlock <int>(async(x) =>
            {
                await Task.Delay(20);
                Console.WriteLine("Block2: " + x);
            }, executionDataflowBlockOptions);
            ActionBlock <int> action3 = new ActionBlock <int>(async(x) =>
            {
                await Task.Delay(200);
                Console.WriteLine("Block3: " + x);
            }, executionDataflowBlockOptions);

            var buffer1 = new BufferBlock <int>();

            buffer1.LinkTo(action1);

            foreach (var i in Enumerable.Range(1, 100))
            {
                buffer1.Post(i);
            }
            Console.ReadKey();



            var jb = new JoinBlock <int, string>();

            jb.Target1.Post(1);
            jb.Target2.Post("Name1");
            Console.WriteLine(jb.Receive());


            Console.WriteLine("Done");
            Console.ReadKey();

            //Join();
            //Console.ReadKey();

            //var bufferBlock = new BufferBlock<int>();
            //var broadCast = new BroadcastBlock<int>(x => x + 10);
            //var writeOnceBlock = new WriteOnceBlock<int>((a) => a + 100);

            //var writer = new ActionBlock<int>(x => Console.WriteLine(x));

            //var multiplyer = new TransformBlock<int, int>(x => x * x);
            //var multiplyerMany = new TransformManyBlock<int, int>(x => Enumerable.Range(0, x).ToList());

            //var joinBlock = new JoinBlock<int, int>();
            //var batchBlock = new BatchBlock<int>(1000);
            //var bacthedJoinBlock = new BatchedJoinBlock<int, int>(2);

            ////AsyncDownloading();
            //Console.ReadKey();
        }