Пример #1
0
        static void Main(string[] args)
        {
            string s =
                "http://cn.bing.com/search?q=MD5CryptoServiceProvider+slow&qs=n&pq=md5cryptoserviceprovider+slow&sc=0-25&sp=-1&sk=&cvid=67d40cbd8c424d55a3db83e6e9868267&first=51&FORM=PERE4";
            using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
            {
                byte[] inBytes = Encoding.UTF8.GetBytes(s);
                var bytes = md5.ComputeHash(inBytes);
                Console.WriteLine(bytes.Length);
            }


            var splitter = new TransformBlock<string, KeyValuePair<string, int>>(
                input =>
                    {
                        var splitted = input.Split('=');
                        return new KeyValuePair<string, int>(splitted[0], int.Parse(splitted[1]));
                    });

            var dict = new Dictionary<string, int>();
            var aggregater = new ActionBlock<KeyValuePair<string, int>>(
                pair =>
                    {
                        int oldValue;
                        dict[pair.Key] = dict.TryGetValue(pair.Key, out oldValue) ? oldValue + pair.Value : pair.Value;
                    });

            splitter.LinkTo(aggregater, new DataflowLinkOptions() { PropagateCompletion = true});

            splitter.Post("a=1");
            splitter.Post("b=2");
            splitter.Post("a=5");

            splitter.Complete();
            aggregater.Completion.Wait();
            Console.WriteLine("sum(a) = {0}", dict["a"]); //prints sum(a) = 6


            //CalcAsync().Wait();
            //SlowFlowAsync().Wait();
            //FailDemoAsync().Wait();
            //TransformAndLinkDemo().Wait();
            //LinkLeftToDemo().Wait();
            //CircularFlowAutoComplete().Wait();
            //RecorderDemo().Wait();
            BulkInserterDemo().Wait();
            //BulkInserterDemo2().Wait();
            //BroadcasterDemo().Wait();
            //MyLoggerDemo().Wait();
            //ETLLookupDemo().Wait();
        }
Пример #2
0
        static void Main1(string[] args)
        {
            // Create a shared CancellationTokenSource object to enable the
            // TrySolution method to be cancelled.
            var cts = new CancellationTokenSource();

            // Create three TransformBlock<int, int> objects.
            // Each TransformBlock<int, int> object calls the TrySolution method.
            Func <int, int> action       = n => TrySolution(n, cts.Token);
            var             trySolution1 = new TransformBlock <int, int>(action);
            var             trySolution2 = new TransformBlock <int, int>(action);
            var             trySolution3 = new TransformBlock <int, int>(action);

            // Post data to each TransformBlock<int, int> object.
            trySolution1.Post(11);
            trySolution2.Post(21);
            trySolution3.Post(31);

            // Call the ReceiveFromAny<T> method to receive the result from the
            // first TransformBlock<int, int> object to finish.
            int result = ReceiveFromAny(trySolution1, trySolution2, trySolution3);

            // Cancel all calls to TrySolution that are still active.
            cts.Cancel();

            // Print the result to the console.
            Console.WriteLine("The solution is {0}.", result);

            cts.Dispose();
        }
Пример #3
0
        public Task <Package> CompilePackageAsync(
            string name,
            IEnumerable <ICodeFileSource> fileSources,
            FixedDictionary <string, Task <Package> > references,
            TaskScheduler taskScheduler)
        {
            var lexer      = new Lexer();
            var parser     = new CompilationUnitParser();
            var parseBlock = new TransformBlock <ICodeFileSource, CompilationUnitSyntax>(
                async(fileSource) =>
            {
                var file    = await fileSource.LoadAsync();
                var context = new ParseContext(file, new Diagnostics());
                var tokens  = lexer.Lex(context).WhereNotTrivia();
                return(parser.Parse(tokens));
            }, new ExecutionDataflowBlockOptions()
            {
                TaskScheduler = taskScheduler,
                EnsureOrdered = false,
            });

            foreach (var fileSource in fileSources)
            {
                parseBlock.Post(fileSource);
            }

            parseBlock.Complete();

            throw new NotImplementedException();
        }
Пример #4
0
        public static async Task Linking()
        {
            var multiplyBlock = new TransformBlock <int, int>(item => item * 2);
            var subtractBlock = new TransformBlock <int, int>(item =>
            {
                return(item - 2);
            });

            multiplyBlock.LinkTo(subtractBlock, new DataflowLinkOptions
            {
                PropagateCompletion = true
            });

            foreach (var item in Enumerable.Repeat(1, 10).ToArray())
            {
                multiplyBlock.Post(item);
            }

            multiplyBlock.Complete();

            /*
             *      Microsoft documentation is kinda misleading about waiting for the final block to complete
             *      whether a block is completed or not depends on the type of the block
             *      TransformBlock needs 3 conditions
             *      1/ TransformBlock.Complete() has been called
             *      2/ InputCount == 0 the block has applied its transformation to every incoming element
             *      3/ Outputcount == 0 all transformed elements have left the output buffer
             */
            await subtractBlock.Completion;

            System.Console.WriteLine("Done"); // this part is unreachable
        }
Пример #5
0
        public override void Run()
        {
            /* Unbounded 表示块使用支持的最大并行数
             * 块并行处理时,处理的数据顺序不一定与接收的顺序一致,但是输出时与接收的顺序一致
             */
            TransformBlock <RunModel, string> transformBlock = new TransformBlock <RunModel, string>(
                (model) =>
            {
                Helper.PrintLine($"开始处理 {model.Name}");
                return($"I'm {model.Name}");
            },
                new ExecutionDataflowBlockOptions()
            {
                MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded
            });

            var models = this.CreateCollection();

            // TransformBlock 可以同时作为输入和输出
            Array.ForEach(models, model => transformBlock.Post(model));
            for (int index = 0; index < models.Length; index++)
            {
                Helper.PrintLine(transformBlock.Receive());
            }
        }
Пример #6
0
        public Task GenerateTests(List <string> files, DegreeOfParallelism degree)
        {
            var readFile = new TransformBlock <string, string>(
                new Func <string, Task <string> >(reader.ReadCodeFromFile), new ExecutionDataflowBlockOptions
            {
                MaxDegreeOfParallelism = degree.AmountOfReadParallelProcess
            });
            var generateTests = new TransformBlock <string, List <TestClassDetails> >(
                new Func <string, List <TestClassDetails> >(GetDetailsFromSourceCode), new ExecutionDataflowBlockOptions
            {
                MaxDegreeOfParallelism = degree.AmountOfGenerateParallelProcess
            });
            var writeTestsToFile = new ActionBlock <List <TestClassDetails> >(
                tests => writer.WriteTestsToFiles(tests), new ExecutionDataflowBlockOptions
            {
                MaxDegreeOfParallelism = degree.AmountOfWriteParallelProcess
            });

            var linkOptions = new DataflowLinkOptions {
                PropagateCompletion = true
            };

            readFile.LinkTo(generateTests, linkOptions);
            generateTests.LinkTo(writeTestsToFile, linkOptions);

            foreach (var file in files)
            {
                readFile.Post(file);
            }

            readFile.Complete();
            return(writeTestsToFile.Completion);
        }
        static async Task Main(string[] args)
        {
            var producer1 = new TransformBlock <string, string>(async n =>
            {
                await Task.Delay(150);
                return(n);
            });

            var producer2 = new TransformBlock <string, string>(n =>
            {
                Task.Delay(500).Wait();
                return(n);
            });

            var printBlock = new ActionBlock <string>(n => Console.WriteLine(n));

            producer1.LinkTo(printBlock);
            producer2.LinkTo(printBlock);

            for (int i = 0; i < 10; i++)
            {
                producer1.Post($"Producer 1 message: {i}");
                producer2.Post($"Producer 2 message: {i}");
            }

            producer1.Complete();
            producer2.Complete();
            await Task.WhenAll(new[] { producer1.Completion, producer2.Completion })
            .ContinueWith(_ => printBlock.Complete())
            .ContinueWith(_ => printBlock.Completion);

            Console.WriteLine("done");
            Console.ReadLine();
        }
        public void PropagateCompletionAfterWaitTest()
        {
            var evt = new ManualResetEventSlim();

            var source = new TransformBlock <int, int> (
                i =>
            {
                evt.Wait();
                return(i);
            });
            var target = new BufferBlock <int> ();

            Assert.IsNotNull(source.LinkTo(target,
                                           new DataflowLinkOptions {
                PropagateCompletion = true
            }));

            Assert.IsTrue(source.Post(42));

            Assert.IsFalse(target.Completion.Wait(100));

            source.Complete();
            Assert.IsFalse(target.Completion.Wait(100));

            evt.Set();
            Assert.IsFalse(target.Completion.Wait(100));

            Assert.AreEqual(42, target.Receive());
            Assert.IsTrue(target.Completion.Wait(1000));
        }
Пример #9
0
        private static void Main()
        {
            //var greedy = new ExecutionDataflowBlockOptions();
            var nonGreedy = new ExecutionDataflowBlockOptions {
                BoundedCapacity = 1
            };

            var options = nonGreedy;

            var firstBlock  = new ActionBlock <int>(i => Do(i, 1, 2), options);
            var secondBlock = new ActionBlock <int>(i => Do(i, 2, 1), options);
            var thirdBlock  = new ActionBlock <int>(i => Do(i, 3, 2), options);

            var transform = new TransformBlock <int, int>(i => i * 2);

            transform.LinkTo(firstBlock);
            transform.LinkTo(secondBlock);
            transform.LinkTo(thirdBlock);

            for (var i = 0; i <= 10; i++)
            {
                transform.Post(i);
            }

            Console.ReadLine();
        }
Пример #10
0
        private static void Main()
        {
            Tuple <string, bool> IsHappy(string url)
            {
                Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
                using (var client = new WebClient())
                {
                    var content = client.DownloadString(url);
                    return(Tuple.Create(url, content.ToLower().Contains("happy")));
                }
            }

            var happySites       = new List <string>();
            var isHappySiteBlock = new TransformBlock <string, Tuple <string, bool> >(
                (Func <string, Tuple <string, bool> >)IsHappy,
                new ExecutionDataflowBlockOptions {
                MaxDegreeOfParallelism = 1
            });

            var addToHappySiteBlock = new ActionBlock <Tuple <string, bool> >(tuple => happySites.Add(tuple.Item1));

            isHappySiteBlock.LinkTo(
                addToHappySiteBlock, new DataflowLinkOptions {
                PropagateCompletion = true
            }, tuple => tuple.Item2);

            isHappySiteBlock.LinkTo(
                DataflowBlock.NullTarget <Tuple <string, bool> >());

            Array.ForEach(_HappySites, url => isHappySiteBlock.Post(url));

            isHappySiteBlock.Complete();
            addToHappySiteBlock.Completion.Wait();
            happySites.ForEach(Console.WriteLine);
        }
Пример #11
0
        public void TestBoundedCapacity()
        {
            var t1 = new TransformBlock <int, int>(x => x + 2);
            var t2 = new TransformBlock <int, string>(x => (x * 2).ToString());
            var b  = new BufferBlock <string>(new DataflowBlockOptions {
                BoundedCapacity = 1
            });

            var log  = new TransformBlock <string, string>(x => { Console.WriteLine($"TransformBlock has {x}"); return(x); });
            var test = new ActionBlock <string>(x => Assert.Equal("8", x));

            var options = new DataflowLinkOptions {
                PropagateCompletion = true
            };

            t1.LinkTo(t2, options);
            t2.LinkTo(b, options);
            b.LinkTo(log, options);
            log.LinkTo(test, options);


            t1.Post(2);
            t1.Complete();

            test.Completion.Wait();
        }
Пример #12
0
        internal static void Run()
        {
            var tempFile = CreateRandomFile();

            // Create an ActionBlock<int> object that prints to the console
            // the number of bytes read.
            var printResult = new ActionBlock <int>(zeroBytesRead =>
            {
                Console.WriteLine("{0} contains {1} zero bytes.", Path.GetFileName(tempFile), zeroBytesRead);
            });

            // Create a TransformBlock<string, int> object that calls the
            // CountBytes function and returns its result.
            var countBytes = new TransformBlock <string, int>(new Func <string, Task <int> >(CountBytes));

            // Link the TransformBlock<string, int> object to the ActionBlock<int> object.
            countBytes.LinkTo(printResult);
            countBytes.Completion.ContinueWith(delegate { printResult.Complete(); });

            // Post the path to the temporary file to the
            // TransformBlock<string, int> object.
            countBytes.Post(tempFile);

            // Requests completion of the TransformBlock<string, int> object.
            countBytes.Complete();

            // Wait for the ActionBlock<int> object to print the message.
            printResult.Completion.Wait();

            // Delete the temporary file.
            File.Delete(tempFile);
        }
Пример #13
0
        public void Run()
        {
            ConcurrentBag <int> values = new ConcurrentBag <int>();
            var transformBlock         = new TransformBlock <int, string>(n =>
            {
                Task.Delay(500).Wait();
                values.Add(n);
                return(n.ToString());
            }, new ExecutionDataflowBlockOptions()
            {
                MaxDegreeOfParallelism = 4
            });

            for (int i = 0; i < 10; i++)
            {
                transformBlock.Post(i);
                Console.WriteLine("Input count:" + transformBlock.InputCount);
            }

            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("output count:" + transformBlock.OutputCount);
                var result     = transformBlock.Receive();
                var listResult = 0;
                values.TryTake(out listResult);
                Console.WriteLine($"Result:{result}  Output count:{transformBlock.OutputCount} input count:{transformBlock.InputCount} list item: {listResult}");
            }
        }
Пример #14
0
 static async void Example4()
 {
     try
     {
         var multiplyBlock = new TransformBlock <int, int>(item =>
         {
             if (item == 1)
             {
                 throw new InvalidOperationException("Blech.");
             }
             return(item * 2);
         });
         var subtracktBlock = new TransformBlock <int, int>(item => item - 2);
         multiplyBlock.LinkTo(subtracktBlock, new DataflowLinkOptions {
             PropagateCompletion = true
         });
         multiplyBlock.Post(1);
         await subtracktBlock.Completion;
     }
     catch (AggregateException ae)
     {
         //这里捕获异常。
         ae.Flatten();
     }
 }
        public static async Task DataFlowIntro()
        {
            try
            {
                var multiplyBlock = new TransformBlock <int, int>(item =>
                {
                    if (item == 1)
                    {
                        throw new InvalidOperationException("Blech.");
                    }

                    return(item * 2);
                });
                var subtractBlock = new TransformBlock <int, int>(item => item - 2);
                multiplyBlock.LinkTo(subtractBlock, new DataflowLinkOptions {
                    PropagateCompletion = true
                });

                multiplyBlock.Post(10);
                await subtractBlock.Completion;
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }
        public async Task TestPrecanceled()
        {
            var bb = new TransformBlock <int, int>(i => i,
                                                   new ExecutionDataflowBlockOptions {
                CancellationToken = new CancellationToken(canceled: true)
            });

            int         ignoredValue;
            IList <int> ignoredValues;

            IDisposable link = bb.LinkTo(DataflowBlock.NullTarget <int>());

            Assert.NotNull(link);
            link.Dispose();

            Assert.False(bb.Post(42));
            var t = bb.SendAsync(42);

            Assert.True(t.IsCompleted);
            Assert.False(t.Result);

            Assert.False(bb.TryReceiveAll(out ignoredValues));
            Assert.False(bb.TryReceive(out ignoredValue));

            Assert.NotNull(bb.Completion);
            await Assert.ThrowsAnyAsync <OperationCanceledException>(() => bb.Completion);

            bb.Complete(); // just make sure it doesn't throw
        }
Пример #17
0
        /// <summary>
        /// Generate tests classes.
        /// </summary>
        /// <param name="reader">File reader.</param>
        /// <param name="writer">File writer.</param>
        /// <param name="source">Paths to files.</param>
        /// <returns></returns>
        public async Task Generate(CodeReader reader, CodeWriter writer, List <string> source)
        {
            DataflowLinkOptions linkOptions = new DataflowLinkOptions {
                PropagateCompletion = true
            };
            ExecutionDataflowBlockOptions processingTaskRestriction = new ExecutionDataflowBlockOptions {
                MaxDegreeOfParallelism = _testsGeneratorConfig.MaxProcessingTasksCount
            };
            ExecutionDataflowBlockOptions outputTaskRestriction = new ExecutionDataflowBlockOptions {
                MaxDegreeOfParallelism = _testsGeneratorConfig.MaxWritingTasksCount
            };

            TransformBlock <string, string> readingBlock =
                new TransformBlock <string, string>(new Func <string, Task <string> >(reader.ReadAsync), processingTaskRestriction);

            TransformBlock <string, GeneratedTestClass> producingBlock =
                new TransformBlock <string, GeneratedTestClass>(new Func <string, GeneratedTestClass>(Produce), processingTaskRestriction);

            ActionBlock <GeneratedTestClass> writingBlock = new ActionBlock <GeneratedTestClass>(
                ((generatedClass) => writer.WriteAsync(generatedClass).Wait()), outputTaskRestriction);

            readingBlock.LinkTo(producingBlock, linkOptions);
            producingBlock.LinkTo(writingBlock, linkOptions);

            foreach (string path in source)
            {
                readingBlock.Post(path);
            }

            readingBlock.Complete();

            await writingBlock.Completion;
        }
Пример #18
0
        static void Main(string[] args)
        {
            var options = new GroupingDataflowBlockOptions {
                Greedy = false
            };
            var sync = new BatchBlock <string>(3, options);

            // the delegate returns value tuple (.MET 4.7 / standard 2.0)
            var chA = new TransformBlock <int, string>(
                (Func <int, string>)ChannelA);
            var chB = new TransformBlock <int, string>(
                (Func <int, string>)ChannelB);
            var chC = new TransformBlock <int, string>(
                (Func <int, Task <string> >)ChannelC);

            var presenter = new ActionBlock <string[]>((Action <string[]>)Present);

            chA.LinkTo(sync);
            chB.LinkTo(sync);
            chC.LinkTo(sync);
            sync.LinkTo(presenter);


            for (int i = 1; i <= 20; i++)
            {
                chA.Post(i);
                chB.Post(i);
                chC.Post(i);
            }

            Console.ReadKey();
        }
Пример #19
0
        public async Task Can_TransformBlock_Be_Observable_And_Linked()
        {
            var totalValuesRecievedByActionBlock = new List <int>();
            var totalValuesRecievedInStream      = new List <int>();
            var streamCompletionSource           = new TaskCompletionSource <bool>();

            var transformBlock = new TransformBlock <int, int>(_ => _);
            var actionBlock    = new ActionBlock <int>(x => Task.Delay(1000).ContinueWith(_ => totalValuesRecievedByActionBlock.Add(x)), new ExecutionDataflowBlockOptions()
            {
                BoundedCapacity = 1
            });

            var subscription = transformBlock.AsObservable().Subscribe(x => totalValuesRecievedInStream.Add(x),
                                                                       () => streamCompletionSource.SetResult(true));

            var actionLink = transformBlock.LinkTo(actionBlock, new DataflowLinkOptions()
            {
                PropagateCompletion = true
            });


            foreach (var item in Enumerable.Range(0, 100))
            {
                transformBlock.Post(item);
            }
            await Task.Delay(2000);

            transformBlock.Complete();
            await actionBlock.Completion;
            await streamCompletionSource.Task;

            Assert.AreEqual(totalValuesRecievedByActionBlock, totalValuesRecievedInStream);
        }
Пример #20
0
        /// <summary>
        /// Running async and return result
        /// @see: https://codereview.stackexchange.com/a/212326
        /// </summary>
        /// <param name="items">!IEnumerableName! (dot) ForEachAsync</param>
        /// <param name="action">Input type</param>
        /// <param name="maxDegreesOfParallelism">Default of 6 task running at the same time </param>
        /// <typeparam name="TSource">output type</typeparam>
        /// <typeparam name="TResult">and output it self</typeparam>
        /// <returns>Task with output</returns>
        public static async Task <IEnumerable <TResult> > ForEachAsync <TSource, TResult>(
            this IEnumerable <TSource> items,
            Func <TSource, Task <TResult> > action,
            int maxDegreesOfParallelism = 6)
        {
            var transformBlock = new TransformBlock <TSource, TResult>(action, new ExecutionDataflowBlockOptions
            {
                MaxDegreeOfParallelism = maxDegreesOfParallelism
            });

            var bufferBlock = new BufferBlock <TResult>();

            using (transformBlock.LinkTo(bufferBlock, new DataflowLinkOptions {
                PropagateCompletion = true
            }))
            {
                foreach (var item in items)
                {
                    transformBlock.Post(item);
                }

                transformBlock.Complete();
                await transformBlock.Completion;
            }

            bufferBlock.TryReceiveAll(out var result);
            return(result);
        }
Пример #21
0
        private static async Task SequentialForkAsync()
        {
            // the output of transform block is sequential
            // (dictate by the order of the original input)
            IPropagatorBlock <int, string> block =
                new TransformBlock <int, string>(i => UnitOfWorkAsync(i),
                                                 new ExecutionDataflowBlockOptions {
                MaxDegreeOfParallelism = ITERATIONS
            });

            // the action block will get the transformation in the original order
            var ab = new ActionBlock <string>(m => Console.WriteLine($"# Action: {m}"));

            block.LinkTo(ab, new DataflowLinkOptions {
                PropagateCompletion = true
            });

            for (int i = 0; i < ITERATIONS; i++)
            {
                block.Post(i);
            }

            block.Complete();
            await ab.Completion.ConfigureAwait(false);

            Console.WriteLine("Done");
        }
Пример #22
0
        public static void Run()
        {
            Func <int, int> fn = n =>
            {
                Thread.Sleep(1000);
                return(n * n);
            };

            var tfBlock = new TransformBlock <int, int>(fn);

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

            // Receive Async returns a Task
            for (int i = 0; i < 10; i++)
            {
                Task <int> resultTask = tfBlock.ReceiveAsync();
                int        result     = resultTask.Result;
                // Calling Result will wait until it has a value ready
                Console.WriteLine(result);
            }

            Console.WriteLine("Done");
            //Instead the ReceiveAsync() method returns a Task<T>
            //that represents the receive operation.Calling the Result() method on the returned Task forces the
            //program to wait until data becomes available essentially making it a synchronous operation like the
            //previous example with the same console output
            //RESULT IS THE SAME
        }
Пример #23
0
        /// <summary>
        /// Process the data.
        /// </summary>
        public static void ProcessData <T1, T2>
        (
            [NotNull] this IEnumerable <T1> data,
            [NotNull] TransformBlock <T1, T2> transformBlock,
            [NotNull] ActionBlock <T2> actionBlock
        )
        {
            Code.NotNull(data, "data");
            Code.NotNull(transformBlock, "transformBlock");
            Code.NotNull(actionBlock, "actionBlock");

            DataflowLinkOptions options = new DataflowLinkOptions
            {
                PropagateCompletion = true
            };

            transformBlock.LinkTo(actionBlock, options);

            foreach (T1 item in data)
            {
                transformBlock.Post(item);
            }

            transformBlock.Complete();
            actionBlock.Completion.Wait();
        }
Пример #24
0
        public override Task GenerateTests(IEnumerable <string> classFiles, string pathToSave, int maxFileToRead, int maxThreads, int maxFileToWrite)
        {
            var maxFilesToLoadTasks = new ExecutionDataflowBlockOptions {
                MaxDegreeOfParallelism = maxFileToRead
            };
            var maxTasksExecutedTasks = new ExecutionDataflowBlockOptions {
                MaxDegreeOfParallelism = maxThreads
            };
            var maxFilesToWriteTasks = new ExecutionDataflowBlockOptions {
                MaxDegreeOfParallelism = maxFileToWrite
            };

            var getText = new TransformBlock <string, string>(GetTextFromFileAsync, maxFilesToLoadTasks);

            var getTests = new TransformBlock <string, string[]>(GetTestsFromText, maxTasksExecutedTasks);

            _pathToSave = pathToSave;
            var saveTests = new ActionBlock <string[]>(SaveTests, maxFilesToWriteTasks);

            //to propagate message after IDataflowBlock.Complete()
            var linkOptions = new DataflowLinkOptions {
                PropagateCompletion = true
            };

            getText.LinkTo(getTests, linkOptions);
            getTests.LinkTo(saveTests, linkOptions);
            foreach (var file in classFiles)
            {
                getText.Post(file);
            }
            getText.Complete();

            return(saveTests.Completion);
        }
        public async Task TestCircularLinking()
        {
            const int Iters = 200;

            foreach (bool sync in DataflowTestHelpers.BooleanValues)
            {
                var             tcs  = new TaskCompletionSource <bool>();
                Func <int, int> body = i => {
                    if (i >= Iters)
                    {
                        tcs.SetResult(true);
                    }
                    return(i + 1);
                };

                TransformBlock <int, int> tb = sync ?
                                               new TransformBlock <int, int>(body) :
                                               new TransformBlock <int, int>(i => Task.Run(() => body(i)));

                using (tb.LinkTo(tb))
                {
                    tb.Post(0);
                    await tcs.Task;
                    tb.Complete();
                }
            }
        }
Пример #26
0
        static void Main(string[] args)
        {
            var b1 = new TransformBlock <int, string>(i => new string((char)('a' + i), i));
            var b2 = new TransformManyBlock <string, char>(i => i);
            var b3 = new ActionBlock <char>(async c =>
            {
                await Task.Delay(1000).ConfigureAwait(false);
                Console.Write($"{c}, ");
            });
            var b4 = new ActionBlock <char>(async c =>
            {
                await Task.Delay(500).ConfigureAwait(false);
                Trace.Write($"{c}, ");
            });
            var b5 = new BroadcastBlock <char>(i => i);

            b1.LinkTo(b2);
            b2.LinkTo(b5);
            b5.LinkTo(b3);
            b5.LinkTo(b4);

            for (int i = 1; i <= 10; i++)
            {
                b1.Post(i);
            }

            Console.WriteLine($@"
b1: in {b1.InputCount} out {b1.OutputCount}
b2: in {b2.InputCount} out {b2.OutputCount} 
b3: in {b3.InputCount}
b4: in {b4.InputCount}
");
            Console.ReadKey();
        }
Пример #27
0
        public void TestDegreeOfParallelism()
        {
            var t1 = new TransformBlock <int, int>(x => x * 4);
            var t2 = new TransformBlock <int, string>(
                x => $"Hello number {x}",
                new ExecutionDataflowBlockOptions {
                MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded
            }
                );

            var log  = new TransformBlock <string, string>(x => { Console.WriteLine($"TransformBlock has {x}"); return(x); });
            var test = new ActionBlock <string>(x => Assert.Equal("Hello number 8", x));

            var options = new DataflowLinkOptions {
                PropagateCompletion = true
            };

            t1.LinkTo(t2, options);
            t2.LinkTo(log, options);
            log.LinkTo(test, options);


            t1.Post(2);
            t1.Complete();

            test.Completion.Wait();
        }
Пример #28
0
        public async Task Generate(List <string> inputFiles, string outputPath)
        {
            var linkOptions = new DataflowLinkOptions();

            linkOptions.PropagateCompletion = true;
            var readOptions = new ExecutionDataflowBlockOptions();

            readOptions.MaxDegreeOfParallelism = config.CountOfReadThreads;
            var processOptions = new ExecutionDataflowBlockOptions();

            processOptions.MaxDegreeOfParallelism = config.CountOfProcessThreads;
            var writeOptions = new ExecutionDataflowBlockOptions();

            writeOptions.MaxDegreeOfParallelism = config.CountOfWriteThreads;

            var readBlock    = new TransformBlock <string, string>(fileName => AsyncReader.Read(fileName), readOptions);
            var processBlock = new TransformBlock <string, List <TestInfo> >(sourceCode => GenerateTests(sourceCode), processOptions);
            var writeBlock   = new ActionBlock <List <TestInfo> >(output => AsyncWriter.Write(outputPath, output).Wait(), writeOptions);

            readBlock.LinkTo(processBlock, linkOptions);
            processBlock.LinkTo(writeBlock, linkOptions);
            foreach (string file in inputFiles)
            {
                readBlock.Post(file);
            }
            readBlock.Complete();
            await writeBlock.Completion;
        }
Пример #29
0
        static void Main(string[] args)
        {
            var transformBlock = new TransformBlock <int, string>(n =>
            {
                Task.Delay(500).Wait();
                return(n.ToString());
            },
                                                                  new ExecutionDataflowBlockOptions
            {
                MaxDegreeOfParallelism = 3
            }
                                                                  );

            for (int i = 0; i < 10; i++)
            {
                transformBlock.Post(i);
                Console.WriteLine($"Number of messages in the input queue {transformBlock.InputCount}");
            }

            for (int i = 0; i < 10; i++)
            {
                var result = transformBlock.Receive();
                Console.WriteLine($"Received:{result}");
                Console.WriteLine($"Number of messages in the output queue {transformBlock.OutputCount}");
            }

            Console.WriteLine("Finished!");
            Console.Read();
        }
Пример #30
0
        private static async Task SimpleDemoWithDelayAsync()
        {
            Console.WriteLine("TransformBlockDemo has started!");
            var block = new TransformBlock <int, string>( // by default singlethreaded
                async(input) =>
            {
                await Task.Delay(500).ConfigureAwait(false);
                return(input.ToString());
            });

            for (int i = 0; i < 10; i++)
            {
                block.Post(i);
                Console.WriteLine($"TransformBlock input queue count: {block.InputCount}");
            }

            block.Complete(); // No mo data.

            while (await block.OutputAvailableAsync().ConfigureAwait(false))
            {
                Console.WriteLine($"TransformBlock OutputCount: {block.InputCount}");
                var output = await block.ReceiveAsync().ConfigureAwait(false);

                Console.WriteLine($"TransformBlock TransformOutput: {output}");
                Console.WriteLine($"TransformBlock OutputCount: {block.OutputCount}"); // will always be 0, since receive data is a blocking action and this transformblock is single threaded
            }

            // wait for completion.
            await block.Completion.ConfigureAwait(false);

            Console.WriteLine("Finished!");
            Console.ReadKey();
        }
Пример #31
0
        public static void Main(string[] args)
        {
            var block = new TransformBlock <int, string>(n =>
            {
                if (n == 5)
                {
                    throw new Exception("Something went wrong");
                }
                return($"Message {n} processed");
            }
                                                         );
            var printBlock = new ActionBlock <string>(x => Console.WriteLine(x));

            block.LinkTo(printBlock, new DataflowLinkOptions {
                PropagateCompletion = true
            });

            for (var i = 0; i < 10; i++)
            {
                if (!block.Post(i))
                {
                    throw new ArgumentException();
                }
            }

            block.Completion.Wait();

            Console.WriteLine("Finished!");
            Console.ReadKey();
        }
Пример #32
0
        static public void ProcessingByTPL_StraightForwardImplementation()
        {
            const string pathToFiles = @"..\..\..\..\DataFiles";
            string[] files = Directory.GetFiles(pathToFiles, "*.txt", SearchOption.AllDirectories);

            var loadDataFromFileBlock = new TransformBlock<string[], List<CustomerTextData>>(fileItems =>
            {
                var factory = new CustomerTextDataFactory();
                return new List<CustomerTextData>(Array.ConvertAll(fileItems, factory.LoadFromFile));
            });
            var filterBlock = new TransformBlock<List<CustomerTextData>, List<CustomerTextData>>(textDataList =>
            {
                var filter = new FilterTextData(5);
                return textDataList.Where(filter.Run).ToList();
            });
            var toListBlock = new TransformManyBlock<List<CustomerTextData>, CustomerTextData>(textDataList =>
            {
                var queue = new ConcurrentQueue<CustomerTextData>();
                textDataList.ForEach(queue.Enqueue);
                return queue;
            });
            var action = new ActionBlock<CustomerTextData>(textData =>
            {
                var weight = new WeightTextData();
                int result = weight.Run(textData);
                Trace.WriteLine(result);
                Console.WriteLine(result);
            });

            loadDataFromFileBlock.LinkTo(filterBlock);
            filterBlock.LinkTo(toListBlock);
            toListBlock.LinkTo(action);

            loadDataFromFileBlock.Completion.ContinueWith(t =>
            {
                if (t.IsFaulted) ((IDataflowBlock)filterBlock).Fault(t.Exception);
                else filterBlock.Complete();
            });
            filterBlock.Completion.ContinueWith(t =>
            {
                if (t.IsFaulted) ((IDataflowBlock)toListBlock).Fault(t.Exception);
                else toListBlock.Complete();
            });
            toListBlock.Completion.ContinueWith(t =>
            {
                if (t.IsFaulted) ((IDataflowBlock)action).Fault(t.Exception);
                else action.Complete();
            });

            loadDataFromFileBlock.Post(files);
            loadDataFromFileBlock.Complete();
            action.Completion.Wait();
        }
Пример #33
0
        private static TransformBlock<int, string> ConstructTransformWithNMessages(int messagesCount)
        {
            var block = new TransformBlock<int, string>(i => i.ToString());
            for (int i = 0; i < messagesCount; i++)
            {
                block.Post(i);
            }

            // Spin until the messages have been properly buffered up. 
            // Otherwise TryReceive fails.
            SpinWait.SpinUntil(() => block.OutputCount == messagesCount);

            return block;
        }
Пример #34
0
		public void BasicUsageTest ()
		{
			int[] array = new int[10];
			var evt = new ManualResetEventSlim (false);
			ActionBlock<int> action = new ActionBlock<int> ((i) => { array[Math.Abs (i)] = i; evt.Set (); });
			TransformBlock<int, int> block = new TransformBlock<int, int> (i => -i);
			block.LinkTo (action);

			for (int i = 0; i < array.Length; ++i)
				Assert.IsTrue (block.Post (i), "Not accepted");

			evt.Wait ();

			CollectionAssert.AreEqual (new int[] { 0, -1, -2, -3, -4, -5, -6, -7, -8, -9 }, array);
		}
Пример #35
0
		public void DeferredUsageTest ()
		{
			int[] array = new int[10];
			var action = new ActionBlock<int> (i => array[Math.Abs (i)] = i);
			var block = new TransformBlock<int, int> (i => -i);

			for (int i = 0; i < array.Length; ++i)
				Assert.IsTrue (block.Post (i), "Not accepted");

			Thread.Sleep (300);
			block.LinkTo (action);
			Thread.Sleep (100);

			CollectionAssert.AreEqual (new[] { 0, -1, -2, -3, -4, -5, -6, -7, -8, -9 }, array);
		}
Пример #36
0
        internal static bool TransformThroughFilterToAction()
        {
            const int ITERS = 2;
            int completedCount = 0;

            var t = new TransformBlock<int, int>(i => i);
            var c = new ActionBlock<int>(i => completedCount++);

            t.LinkTo(c, i => true);
            t.Completion.ContinueWith(_ => c.Complete());

            for (int i = 0; i < ITERS; i++) t.Post(i);
            t.Complete();
            c.Completion.Wait();

            return completedCount == ITERS;
        }
Пример #37
0
		public void AsyncNullTest ()
		{
			var scheduler = new TestScheduler ();
			var block = new TransformBlock<int, int> (
				i => null,
				new ExecutionDataflowBlockOptions { TaskScheduler = scheduler });

			Assert.IsTrue (block.Post (1));

			scheduler.ExecuteAll ();

			Assert.IsFalse (block.Completion.Wait (100));

			block.Complete ();

			Assert.IsTrue (block.Completion.Wait (100));
		}
Пример #38
0
        public void Run()
        {
            var options = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 8 };

            var tb = new TransformBlock<int, int>(i => i * 2);
            var ab = new ActionBlock<int>(i => this.Compute(i), options);
            tb.LinkTo(ab);

            for (var i = 0; i < 10; i++)
            {
                tb.Post(i);
            }

            tb.Complete();
            tb.Completion.Wait();

            Thread.Sleep(500);
        }
Пример #39
0
        public static void Example1()
        {
            var conf = new ExecutionDataflowBlockOptions() { MaxDegreeOfParallelism = 4 };

            ActionBlock<int> a = new ActionBlock<int>(i =>
            {
                Thread.Sleep(500);
                Console.WriteLine(i);
            }, conf);
            TransformBlock<int, int> t = new TransformBlock<int, int>(i => i * 3);

            t.LinkTo(a);

            for (int i = 0; i < 12; i++)
            {
                t.Post(i);
            }
        }
        public async Task TestBlockBufferCount()
        {
            var block1 = new TransformBlock<int, int>(i => 2 * i);
            var block2 = new TransformManyBlock<int, int>(i => new [] { i });
            var block3 = new ActionBlock<int>(i => { Thread.Sleep(1000); });

            block1.Post(0);
            block2.Post(0);
            block2.Post(0);
            block3.Post(0);
            block3.Post(0);
            block3.Post(0);

            await Task.Delay(200);

            Assert.AreEqual(1, block1.GetBufferCount().Total());
            Assert.AreEqual(2, block2.GetBufferCount().Total());
            Assert.AreEqual(2, block3.GetBufferCount().Total());
        }
Пример #41
0
		public void BasicUsageTest ()
		{
			int[] array = new int[10];
			var evt = new CountdownEvent (10);
			var action = new ActionBlock<int> (i =>
			{
				array [Math.Abs (i)] = i;
				evt.Signal ();
			});
			var block = new TransformBlock<int, int> (i => -i);
			block.LinkTo (action);

			for (int i = 0; i < array.Length; ++i)
				Assert.IsTrue (block.Post (i), "Not accepted");

			evt.Wait ();

			CollectionAssert.AreEqual (
				new[] { 0, -1, -2, -3, -4, -5, -6, -7, -8, -9 }, array);
		}
Пример #42
0
        internal static bool TransformToAction()
        {
            bool passed = true;
            const int ITERS = 2;

            var t = new TransformBlock<int, int>(i => i * 2);
            int completedCount = 0;
            int prev = -2;
            var c = new ActionBlock<int>(i =>
            {
                completedCount++;
                if (i != prev + 2) passed &= false;
                prev = i;
            });
            t.LinkWithCompletion(c);

            for (int i = 0; i < ITERS; i++) t.Post(i);
            t.Complete();
            c.Completion.Wait();
            Assert.True(completedCount == ITERS);

            return passed;
        }
Пример #43
0
        public async static void TData()
        {
            var multiplyBlock = new TransformBlock<int, int>(item =>
            {
                var res = item * 2;
                Console.WriteLine("{0} * 2 = {1}", item, res);
                return res;
            });

            var divideBlock = new TransformBlock<int, int>(item =>
            {
                var res = item / 2;
                Console.WriteLine("{0} / 2 = {1}", item, res);
                return res;
            });

            multiplyBlock.LinkTo(divideBlock);

            multiplyBlock.Post(2);

            multiplyBlock.Complete();
            await divideBlock.Completion;
        }
Пример #44
0
        static void Main(string[] args)
        {
            var multiplyBlock = new TransformBlock<int, int>(value => value * 2);
            var subtractBlock = new TransformBlock<int, int>(value => value - 2);
            var displayBlock = new ActionBlock<int>(value => Console.WriteLine(value));

            // multiplyBlock ==> subtractBlock ==> displayBlock
            var linkOptions = new DataflowLinkOptions { PropagateCompletion = true };
            multiplyBlock.LinkTo(subtractBlock, linkOptions);
            subtractBlock.LinkTo(displayBlock, linkOptions);

            // Put data in the first block (multiplyBlock)
            foreach (var i in Enumerable.Range(0, 10))
                multiplyBlock.Post(i);

            // Mark it as complete. Completion will propagate because of the link options.
            multiplyBlock.Complete();

            // Wait for the last block (displayBlock) to complete.
            displayBlock.Completion.Wait();

            Console.ReadKey();
        }
Пример #45
0
 public async Task TestFaultyLinkedTarget()
 {
     var tb = new TransformBlock<int, int>(i => i);
     tb.LinkTo(new DelegatePropagator<int, int>
     {
         OfferMessageDelegate = delegate { throw new InvalidCastException(); }
     });
     tb.Post(42);
     await Assert.ThrowsAsync<InvalidCastException>(() => tb.Completion);
 }
Пример #46
0
        public async Task TestPrecanceled()
        {
            var bb = new TransformBlock<int, int>(i => i,
                new ExecutionDataflowBlockOptions { CancellationToken = new CancellationToken(canceled: true) });

            int ignoredValue;
            IList<int> ignoredValues;

            IDisposable link = bb.LinkTo(DataflowBlock.NullTarget<int>());
            Assert.NotNull(link);
            link.Dispose();
            
            Assert.False(bb.Post(42));
            var t = bb.SendAsync(42);
            Assert.True(t.IsCompleted);
            Assert.False(t.Result);

            Assert.False(bb.TryReceiveAll(out ignoredValues));
            Assert.False(bb.TryReceive(out ignoredValue));

            Assert.NotNull(bb.Completion);
            await Assert.ThrowsAnyAsync<OperationCanceledException>(() => bb.Completion);
            bb.Complete(); // just make sure it doesn't throw
        }
Пример #47
0
        public async Task TestExceptions()
        {
            var tb1 = new TransformBlock<int, int>((Func<int, int>)(i => { throw new InvalidCastException(); }));
            var tb2 = new TransformBlock<int, int>((Func<int, Task<int>>)(i => { throw new InvalidProgramException(); }));
            var tb3 = new TransformBlock<int, int>((Func<int, Task<int>>)(i => Task.Run((Func<int>)(() => { throw new InvalidTimeZoneException(); }))));

            for (int i = 0; i < 3; i++)
            {
                tb1.Post(i);
                tb2.Post(i);
                tb3.Post(i);
            }

            await Assert.ThrowsAsync<InvalidCastException>(() => tb1.Completion);
            await Assert.ThrowsAsync<InvalidProgramException>(() => tb2.Completion);
            await Assert.ThrowsAsync<InvalidTimeZoneException>(() => tb3.Completion);

            Assert.All(new[] { tb1, tb2, tb3 }, tb => Assert.True(tb.InputCount == 0 && tb.OutputCount == 0));
        }
Пример #48
0
        public async Task TestReserveReleaseConsume()
        {
            var tb = new TransformBlock<int, int>(i => i * 2);
            tb.Post(1);
            await DataflowTestHelpers.TestReserveAndRelease(tb);

            tb = new TransformBlock<int, int>(i => i * 2);
            tb.Post(2);
            await DataflowTestHelpers.TestReserveAndConsume(tb);
        }
Пример #49
0
        public async Task TestCountZeroAtCompletion()
        {
            var cts = new CancellationTokenSource();
            var tb = new TransformBlock<int, int>(i => i, new ExecutionDataflowBlockOptions() { CancellationToken = cts.Token });
            tb.Post(1);
            cts.Cancel();
            await Assert.ThrowsAnyAsync<OperationCanceledException>(() => tb.Completion);
            Assert.Equal(expected: 0, actual: tb.InputCount);
            Assert.Equal(expected: 0, actual: tb.OutputCount);

            cts = new CancellationTokenSource();
            tb = new TransformBlock<int, int>(i => i);
            tb.Post(1);
            ((IDataflowBlock)tb).Fault(new InvalidOperationException());
            await Assert.ThrowsAnyAsync<InvalidOperationException>(() => tb.Completion);
            Assert.Equal(expected: 0, actual: tb.InputCount);
            Assert.Equal(expected: 0, actual: tb.OutputCount);
        }
Пример #50
0
        private static bool TestQuickStop(bool testThrow)
        {
            bool passed = true;

            CancellationTokenSource cts = new CancellationTokenSource();
            var options = new ExecutionDataflowBlockOptions { CancellationToken = cts.Token };

            var propagator = new TransformBlock<ThrowOn, ThrowOn>(x => { Task.Delay(200).Wait(); return x; }, options);
            var thrower = new ThrowerBlock();

            // Post enough messages to require long processing
            for (int i = 0; i < 2; i++)
                propagator.Post(testThrow && i == 1 ? ThrowOn.OfferMessage : ThrowOn.TryReceive); // Throw on the second message

            // Link the thrower
            propagator.LinkTo(thrower);

            // Once a message has been processed, cancel the propagator (if we are testing cancellation)
            SpinWait.SpinUntil(() => thrower.LastOperation == ThrowOn.OfferMessage);
            if (!testThrow) cts.Cancel();

            // Wait for the propagator to complete
            try
            {
                var ranToCompletion = propagator.Completion.Wait(10000);
                passed = false;
                Console.WriteLine("Task is faulted or canceled (finished: {0}) - FAILED", ranToCompletion ? "ran to copmpletion" : "still running");
            }
            catch (AggregateException ae)
            {
                passed = testThrow ? ae.InnerException is InvalidOperationException : ae.InnerException is TaskCanceledException;
                ae.Handle(e => true);
                Console.WriteLine("Task is faulted or canceled (exception) - {0}", passed ? "Passed" : "FAILED");
            }

            return passed;
        }
		public Task RunAsync()
		{
			TransformBlock<Uri, PropertyBag> ingestBlock = new TransformBlock<Uri, PropertyBag>(input =>
			{
				PropertyBag result = new PropertyBag
				{
					OriginalUrl = input.ToString(),
					UserAgent = _userAgent,
					Step = new CrawlStep(input, 0)
				};

				return result;
			}, new ExecutionDataflowBlockOptions
			{
				MaxDegreeOfParallelism = MaxDegreeOfParallelism
			});

			TransformBlock<PropertyBag, PropertyBag> ingestBlockForAggregation =
				new TransformBlock<PropertyBag, PropertyBag>(input => input, new ExecutionDataflowBlockOptions
				{
					MaxDegreeOfParallelism = MaxDegreeOfParallelism
				});

			CrawlIngestionHelper crawlIngestionHelper = new CrawlIngestionHelper(ingestBlockForAggregation, _userAgent);
			TransformBlock<PropertyBag, PropertyBag>[] pipeline = Pipeline
				.Select(pipelineStep =>
				{
					return new TransformBlock<PropertyBag, PropertyBag>(async propertyBag =>
					{
						if (propertyBag.StopPipelining)
						{
							return propertyBag;
						}

						try
						{
							propertyBag.StopPipelining = !await pipelineStep.Process(crawlIngestionHelper, propertyBag);
						}
						catch (Exception exception)
						{
							propertyBag.Exceptions.Add(exception);
						}

						return propertyBag;
					}, new ExecutionDataflowBlockOptions
					{
						MaxDegreeOfParallelism = pipelineStep.MaxDegreeOfParallelism
					});
				})
				.ToArray();

			ActionBlock<PropertyBag> terminationCheckerBlock = new ActionBlock<PropertyBag>(propertyBag =>
			{
				if (ingestBlock.InputCount == 0
					&& ingestBlock.OutputCount == 0
					&& !ingestBlock.Completion.IsCompleted
					&& !ingestBlock.Completion.IsCanceled
					&& !ingestBlock.Completion.IsFaulted
					&& ingestBlockForAggregation.InputCount == 0
					&& ingestBlockForAggregation.OutputCount == 0)
				{
					if (pipeline.Any(transformBlock => transformBlock.InputCount != 0 || transformBlock.OutputCount != 0))
					{
						return;
					}

					ingestBlock.Complete();
				}
			}, new ExecutionDataflowBlockOptions {MaxDegreeOfParallelism = 1});

			ingestBlock.LinkTo(ingestBlockForAggregation, new DataflowLinkOptions {PropagateCompletion = true});
			TransformBlock<PropertyBag, PropertyBag> previous = ingestBlockForAggregation;
			foreach (TransformBlock<PropertyBag, PropertyBag> transformBlock in pipeline)
			{
				previous.LinkTo(transformBlock, new DataflowLinkOptions {PropagateCompletion = true});
				previous = transformBlock;
			}

			previous.LinkTo(terminationCheckerBlock, new DataflowLinkOptions {PropagateCompletion = true});
			foreach (Uri startUri in StartUris)
			{
				ingestBlock.Post(startUri);
			}

			return terminationCheckerBlock.Completion;
		}
Пример #52
0
        //[Fact(Skip = "Outerloop")]
        public void RunTransformBlockConformanceTests()
        {
            bool passed = true;

            // SYNC
            #region Sync
            {
                // Do everything twice - once through OfferMessage and Once through Post
                for (FeedMethod feedMethod = FeedMethod._First; passed & feedMethod < FeedMethod._Count; feedMethod++)
                {
                    Func<DataflowBlockOptions, TargetProperties<int>> transformBlockFactory =
                        options =>
                        {
                            TransformBlock<int, int> transformBlock = new TransformBlock<int, int>(i => i, (ExecutionDataflowBlockOptions)options);
                            ActionBlock<int> actionBlock = new ActionBlock<int>(i => TrackCaptures(i), (ExecutionDataflowBlockOptions)options);

                            transformBlock.LinkTo(actionBlock);

                            return new TargetProperties<int> { Target = transformBlock, Capturer = actionBlock, ErrorVerifyable = false };
                        };
                    CancellationTokenSource cancellationSource = new CancellationTokenSource();
                    var defaultOptions = new ExecutionDataflowBlockOptions();
                    var dopOptions = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Environment.ProcessorCount };
                    var mptOptions = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, MaxMessagesPerTask = 2 };
                    var cancellationOptions = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, MaxMessagesPerTask = 2, CancellationToken = cancellationSource.Token };

                    passed &= FeedTarget(transformBlockFactory, defaultOptions, 1, Intervention.None, null, feedMethod, true);
                    passed &= FeedTarget(transformBlockFactory, defaultOptions, 1, Intervention.None, null, feedMethod, true);
                    passed &= FeedTarget(transformBlockFactory, dopOptions, 1, Intervention.None, null, feedMethod, true);
                    passed &= FeedTarget(transformBlockFactory, mptOptions, 1, Intervention.None, null, feedMethod, true);
                    passed &= FeedTarget(transformBlockFactory, mptOptions, 1, Intervention.Complete, null, feedMethod, true);
                    passed &= FeedTarget(transformBlockFactory, cancellationOptions, 1, Intervention.Cancel, cancellationSource, feedMethod, true);
                }

                // Test chained Post/Receive
                {
                    bool localPassed = true;
                    const int ITERS = 2;
                    var network = Chain<TransformBlock<int, int>, int>(4, () => new TransformBlock<int, int>(i => i * 2));
                    for (int i = 0; i < ITERS; i++)
                    {
                        network.Post(i);
                        localPassed &= (((IReceivableSourceBlock<int>)network).Receive() == i * 16);
                    }
                    Console.WriteLine("{0}: Chained Post/Receive", localPassed ? "Success" : "Failure");
                    passed &= localPassed;
                }

                // Test chained SendAsync/Receive
                {
                    bool localPassed = true;
                    const int ITERS = 2;
                    var network = Chain<TransformBlock<int, int>, int>(4, () => new TransformBlock<int, int>(i => i * 2));
                    for (int i = 0; i < ITERS; i++)
                    {
                        network.SendAsync(i);
                        localPassed &= (((IReceivableSourceBlock<int>)network).Receive() == i * 16);
                    }
                    Console.WriteLine("{0}: Chained SendAsync/Receive", localPassed ? "Success" : "Failure");
                    passed &= localPassed;
                }

                // Test chained Post all then Receive
                {
                    bool localPassed = true;
                    const int ITERS = 2;
                    var network = Chain<TransformBlock<int, int>, int>(4, () => new TransformBlock<int, int>(i => i * 2));
                    for (int i = 0; i < ITERS; i++) localPassed &= network.Post(i) == true;
                    for (int i = 0; i < ITERS; i++) localPassed &= ((IReceivableSourceBlock<int>)network).Receive() == i * 16;
                    Console.WriteLine("{0}: Chained Post all then Receive", localPassed ? "Success" : "Failure");
                    passed &= localPassed;
                }

                // Test chained SendAsync all then Receive
                {
                    bool localPassed = true;
                    const int ITERS = 2;
                    var network = Chain<TransformBlock<int, int>, int>(4, () => new TransformBlock<int, int>(i => i * 2));
                    var tasks = new Task[ITERS];
                    for (int i = 1; i <= ITERS; i++) tasks[i - 1] = network.SendAsync(i);
                    Task.WaitAll(tasks);
                    int total = 0;
                    for (int i = 1; i <= ITERS; i++) total += ((IReceivableSourceBlock<int>)network).Receive();
                    localPassed &= (total == ((ITERS * (ITERS + 1)) / 2 * 16));
                    Console.WriteLine("{0}: Chained SendAsync all then Receive", localPassed ? "Success" : "Failure");
                    passed &= localPassed;
                }

                // Test that OperationCanceledExceptions are ignored
                {
                    bool localPassed = true;

                    var t = new TransformBlock<int, int>(i =>
                    {
                        if ((i % 2) == 0) throw new OperationCanceledException();
                        return i;
                    });
                    for (int i = 0; i < 2; i++) t.Post(i);
                    t.Complete();
                    for (int i = 0; i < 2; i++)
                    {
                        if ((i % 2) != 0) localPassed &= t.Receive() == i;
                    }
                    t.Completion.Wait();
                    Console.WriteLine("{0}: OperationCanceledExceptions are ignored", localPassed ? "Success" : "Failure");
                    passed &= localPassed;
                }

                // Test using a precanceled token
                {
                    bool localPassed = true;
                    try
                    {
                        var cts = new CancellationTokenSource();
                        cts.Cancel();
                        var dbo = new ExecutionDataflowBlockOptions { CancellationToken = cts.Token };
                        var t = new TransformBlock<int, int>(i => i, dbo);

                        int ignoredValue;
                        IList<int> ignoredValues;
                        localPassed &= t.LinkTo(new ActionBlock<int>(delegate { })) != null;
                        localPassed &= t.SendAsync(42).Result == false;
                        localPassed &= t.TryReceiveAll(out ignoredValues) == false;
                        localPassed &= t.Post(42) == false;
                        localPassed &= t.OutputCount == 0;
                        localPassed &= t.TryReceive(out ignoredValue) == false;
                        localPassed &= t.Completion != null;
                        t.Complete();
                    }
                    catch (Exception)
                    {
                        localPassed = false;
                    }
                    Console.WriteLine("    {0}: Precanceled tokens work correctly", localPassed ? "Success" : "Failure");
                    passed &= localPassed;
                }

                // Test faulting
                {
                    bool localPassed = true;
                    var t = new TransformBlock<int, int>(new Func<int, int>(i => { throw new InvalidOperationException(); }));
                    t.Post(42);
                    t.Post(1);
                    t.Post(2);
                    t.Post(3);
                    try { t.Completion.Wait(); }
                    catch { }
                    localPassed &= t.Completion.IsFaulted;
                    localPassed &= SpinWait.SpinUntil(() => t.InputCount == 0, 500);
                    localPassed &= SpinWait.SpinUntil(() => t.OutputCount == 0, 500);
                    localPassed &= t.Post(4) == false;
                    Console.WriteLine("    {0}: Faulted handled correctly", localPassed ? "Success" : "Failure");
                    passed &= localPassed;
                }
            }
            #endregion

            #region Async
            // ASYNC (a copy of the sync but with constructors returning Task<T> instead of T
            {
                // Do everything twice - once through OfferMessage and Once through Post
                for (FeedMethod feedMethod = FeedMethod._First; passed & feedMethod < FeedMethod._Count; feedMethod++)
                {
                    Func<DataflowBlockOptions, TargetProperties<int>> transformBlockFactory =
                        options =>
                        {
                            TransformBlock<int, int> transformBlock = new TransformBlock<int, int>(i => Task.Factory.StartNew(() => i), (ExecutionDataflowBlockOptions)options);
                            ActionBlock<int> actionBlock = new ActionBlock<int>(i => TrackCaptures(i), (ExecutionDataflowBlockOptions)options);

                            transformBlock.LinkTo(actionBlock);

                            return new TargetProperties<int> { Target = transformBlock, Capturer = actionBlock, ErrorVerifyable = false };
                        };
                    CancellationTokenSource cancellationSource = new CancellationTokenSource();
                    var defaultOptions = new ExecutionDataflowBlockOptions();
                    var dopOptions = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Environment.ProcessorCount };
                    var mptOptions = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, MaxMessagesPerTask = 2 };
                    var cancellationOptions = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, MaxMessagesPerTask = 2, CancellationToken = cancellationSource.Token };

                    passed &= FeedTarget(transformBlockFactory, defaultOptions, 1, Intervention.None, null, feedMethod, true);
                    passed &= FeedTarget(transformBlockFactory, dopOptions, 10, Intervention.None, null, feedMethod, true);
                    passed &= FeedTarget(transformBlockFactory, mptOptions, 10000, Intervention.None, null, feedMethod, true);
                    passed &= FeedTarget(transformBlockFactory, mptOptions, 10000, Intervention.Complete, null, feedMethod, true);
                    passed &= FeedTarget(transformBlockFactory, cancellationOptions, 10000, Intervention.Cancel, cancellationSource, feedMethod, true);
                }

                // Test chained Post/Receive
                {
                    bool localPassed = true;
                    const int ITERS = 2;
                    var network = Chain<TransformBlock<int, int>, int>(4, () => new TransformBlock<int, int>(i => Task.Factory.StartNew(() => i * 2)));
                    for (int i = 0; i < ITERS; i++)
                    {
                        network.Post(i);
                        localPassed &= (((IReceivableSourceBlock<int>)network).Receive() == i * 16);
                    }
                    Console.WriteLine("{0}: Chained Post/Receive", localPassed ? "Success" : "Failure");
                    passed &= localPassed;
                }

                // Test chained SendAsync/Receive
                {
                    bool localPassed = true;
                    const int ITERS = 2;
                    var network = Chain<TransformBlock<int, int>, int>(4, () => new TransformBlock<int, int>(i => Task.Factory.StartNew(() => i * 2)));
                    for (int i = 0; i < ITERS; i++)
                    {
                        network.SendAsync(i);
                        localPassed &= (((IReceivableSourceBlock<int>)network).Receive() == i * 16);
                    }
                    Console.WriteLine("{0}: Chained SendAsync/Receive", localPassed ? "Success" : "Failure");
                    passed &= localPassed;
                }

                // Test chained Post all then Receive
                {
                    bool localPassed = true;
                    const int ITERS = 2;
                    var network = Chain<TransformBlock<int, int>, int>(4, () => new TransformBlock<int, int>(i => Task.Factory.StartNew(() => i * 2)));
                    for (int i = 0; i < ITERS; i++) localPassed &= network.Post(i) == true;
                    for (int i = 0; i < ITERS; i++) localPassed &= ((IReceivableSourceBlock<int>)network).Receive() == i * 16;
                    Console.WriteLine("{0}: Chained Post all then Receive", localPassed ? "Success" : "Failure");
                    passed &= localPassed;
                }

                // Test chained SendAsync all then Receive
                {
                    bool localPassed = true;
                    const int ITERS = 2;
                    var network = Chain<TransformBlock<int, int>, int>(4, () => new TransformBlock<int, int>(i => Task.Factory.StartNew(() => i * 2)));
                    var tasks = new Task[ITERS];
                    for (int i = 1; i <= ITERS; i++) tasks[i - 1] = network.SendAsync(i);
                    Task.WaitAll(tasks);
                    int total = 0;
                    for (int i = 1; i <= ITERS; i++) total += ((IReceivableSourceBlock<int>)network).Receive();
                    localPassed &= (total == ((ITERS * (ITERS + 1)) / 2 * 16));
                    Console.WriteLine("{0}: Chained SendAsync all then Receive", localPassed ? "Success" : "Failure");
                    passed &= localPassed;
                }

                // Test that OperationCanceledExceptions are ignored
                {
                    bool localPassed = true;

                    var t = new TransformBlock<int, int>(i =>
                    {
                        if ((i % 2) == 0) throw new OperationCanceledException();
                        return Task.Factory.StartNew(() => i);
                    });
                    for (int i = 0; i < 2; i++) t.Post(i);
                    t.Complete();
                    for (int i = 0; i < 2; i++)
                    {
                        if ((i % 2) != 0) localPassed &= t.Receive() == i;
                    }
                    t.Completion.Wait();
                    Console.WriteLine("{0}: OperationCanceledExceptions are ignored", localPassed ? "Success" : "Failure");
                    passed &= localPassed;
                }

                // Test that null tasks are ignored
                {
                    bool localPassed = true;

                    var t = new TransformBlock<int, int>(i =>
                    {
                        if ((i % 2) == 0) return null;
                        return Task.Factory.StartNew(() => i);
                    });
                    for (int i = 0; i < 2; i++) t.Post(i);
                    t.Complete();
                    for (int i = 0; i < 2; i++)
                    {
                        if ((i % 2) != 0) localPassed &= t.Receive() == i;
                    }
                    t.Completion.Wait();
                    Console.WriteLine("{0}: null tasks are ignored", localPassed ? "Success" : "Failure");
                    passed &= localPassed;
                }

                // Test that null tasks are ignored when a reordering buffer is in place
                {
                    bool localPassed = true;

                    var t = new TransformBlock<int, int>(i =>
                    {
                        if (i == 0)
                        {
                            Task.Delay(10).Wait();
                            return null;
                        }
                        return Task.Factory.StartNew(() => i);
                    }, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 2 });
                    t.Post(0);
                    t.Post(1);
                    try
                    {
                        localPassed &= t.Receive(TimeSpan.FromSeconds(4)) == 1;
                    }
                    catch
                    {
                        localPassed = false;
                    }
                    Console.WriteLine("{0}: null tasks are ignored with reordering buffer", localPassed ? "Success" : "Failure");
                    passed &= localPassed;
                }

                // Test faulting from the delegate
                {
                    bool localPassed = true;
                    var t = new TransformBlock<int, int>(new Func<int, Task<int>>(i => { throw new InvalidOperationException(); }));
                    t.Post(42);
                    t.Post(1);
                    t.Post(2);
                    t.Post(3);
                    try { t.Completion.Wait(); }
                    catch { }
                    localPassed &= t.Completion.IsFaulted;
                    localPassed &= SpinWait.SpinUntil(() => t.InputCount == 0, 500);
                    localPassed &= SpinWait.SpinUntil(() => t.OutputCount == 0, 500);
                    localPassed &= t.Post(4) == false;
                    Console.WriteLine("    {0}: Faulted from delegate handled correctly", localPassed ? "Success" : "Failure");
                    passed &= localPassed;
                }

                // Test faulting from the task
                {
                    bool localPassed = true;
                    var t = new TransformBlock<int, int>(new Func<int, Task<int>>(i => Task<int>.Factory.StartNew(() => { throw new InvalidOperationException(); })));
                    t.Post(42);
                    t.Post(1);
                    t.Post(2);
                    t.Post(3);
                    try { t.Completion.Wait(); }
                    catch { }
                    localPassed &= t.Completion.IsFaulted;
                    localPassed &= SpinWait.SpinUntil(() => t.InputCount == 0, 500);
                    localPassed &= SpinWait.SpinUntil(() => t.OutputCount == 0, 500);
                    localPassed &= t.Post(4) == false;
                    Console.WriteLine("    {0}: Faulted from task handled correctly", localPassed ? "Success" : "Failure");
                    passed &= localPassed;
                }
            }
            #endregion

            Assert.True(passed, "Test failed.");
        }
Пример #53
0
        public async Task TransformPingPong()
        {
            TransformBlock<int, int> t1 = null, t2 = null;
            t1 = new TransformBlock<int, int>(i =>
            {
                if (i >= Iterations) t2.Complete();
                return i + 1;
            });
            t2 = new TransformBlock<int, int>(i => i + 1);
            t1.LinkTo(t2);
            t2.LinkTo(t1);

            t1.Post(0);
            await t2.Completion;
        }
Пример #54
0
        //
        // The test that verifies that internally, TransformBlock does not get confused
        // between Func<T, Task<object>> and Func<T, object>.
        //[Fact(Skip = "Outerloop")]
        public void RunTransformCtorOverloadTest()
        {
            bool passed = true;
            {
                Func<object, Task<object>> f = x => Task<object>.FromResult(x);
                TransformBlock<object, object> tf = new TransformBlock<object, object>(f);
                var mre = new ManualResetEvent(false);

                ActionBlock<object> a = new ActionBlock<object>(x =>
                {
                    bool localPassed = !(x is Task<object>);
                    passed &= localPassed;

                    mre.Set();
                });

                tf.LinkTo(a);
                tf.Post(new object());

                mre.WaitOne();
            }
            {
                Func<object, Task<object>> f = x => Task<object>.FromResult(x);
                TransformBlock<object, object> tf = new TransformBlock<object, object>((Func<object, object>)f);
                var mre = new ManualResetEvent(false);

                ActionBlock<object> a = new ActionBlock<object>(x =>
                {
                    bool localPassed = x is Task<object>;
                    passed &= localPassed;

                    mre.Set();
                });

                tf.LinkTo(a);
                tf.Post(new object());

                mre.WaitOne();
            }

            Assert.True(passed, "Test failed.");
        }
Пример #55
0
        internal static bool TransformThroughDiscardingFilterToAction()
        {
            const int ITERS = 2;
            int completedCount = 0;

            var t = new TransformBlock<int, int>(i => i);
            var c = new ActionBlock<int>(i => completedCount++);

            t.LinkTo(c, i => i % 2 == 0);
            t.LinkTo(DataflowBlock.NullTarget<int>());
            t.Completion.ContinueWith(_ => c.Complete());

            for (int i = 0; i < ITERS; i++) t.Post(i);
            t.Complete();
            c.Completion.Wait();

            return completedCount == ITERS / 2;
        }
Пример #56
0
        public async Task TestOrdering_Sync_OrderedDisabled()
        {
            // If ordering were enabled, this test would hang.

            var options = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 2, EnsureOrdered = false };

            var mres = new ManualResetEventSlim();
            var tb = new TransformBlock<int, int>(i =>
            {
                if (i == 0) mres.Wait();
                return i;
            }, options);
            tb.Post(0);
            tb.Post(1);

            Assert.Equal(1, await tb.ReceiveAsync());
            mres.Set();
            Assert.Equal(0, await tb.ReceiveAsync());

            tb.Complete();
            await tb.Completion;
        }
        public async Task PostList(ITargetBlock<Core.Entities.BalanceDate> target)
        {
            Diag.ThreadPrint("PostList - start");

            var transform = new TransformBlock<BalanceDate, Core.Entities.BalanceDate>(ef =>
                 mapper.Map<Core.Entities.BalanceDate>(ef), new ExecutionDataflowBlockOptions() { MaxDegreeOfParallelism = 4 });

            transform.LinkTo(target,new DataflowLinkOptions() { PropagateCompletion = true });

            await Task.Run(() =>
            {
                Diag.ThreadPrint("PostList - task start");

                using (FinanceEntities context = factory.CreateContext())
                {
                    (from b in context.BalanceDates
                                .Include(a => a.BalanceDateBankAccounts)
                                .Include("BalanceDateBankAccounts.BankAccount")
                                .Include("BalanceDateBankAccounts.BankAccount.Bank")
                     select b).AsParallel().ForAll(ef => transform.Post(ef));
                    //await transform.Completion;
                    //transform.Completion.ContinueWith(t =>
                    //{
                    //    if (t.IsFaulted) target.Fault(t.Exception);
                    //    else
                    //    {
                    //        Diag.ThreadPrint("PostList - task set target complete");
                    //        target.Complete();
                    //    }
                    //});
                    transform.Complete();
                }
                Diag.ThreadPrint("PostList - task end");
            }).ConfigureAwait(false);

            Diag.ThreadPrint("PostList - end");
        }
Пример #58
0
        static void Main(string[] args)
        {
            //
            // Create the members of the pipeline.
            //

            // Downloads the requested resource as a string.
            var downloadString = new TransformBlock<string, string>(uri =>
            {
                Console.WriteLine("Downloading '{0}'...", uri);

                return new WebClient().DownloadString(uri);
            });

            // Separates the specified text into an array of words.
            var createWordList = new TransformBlock<string, string[]>(text =>
            {
                Console.WriteLine("Creating word list...");

                // Remove common punctuation by replacing all non-letter characters
                // with a space character to.
                char[] tokens = text.ToArray();
                for (int i = 0; i < tokens.Length; i++)
                {
                    if (!char.IsLetter(tokens[i]))
                        tokens[i] = ' ';
                }
                text = new string(tokens);

                // Separate the text into an array of words.
                return text.Split(new char[] { ' ' },
                   StringSplitOptions.RemoveEmptyEntries);
            });

            // Removes short words, orders the resulting words alphabetically,
            // and then remove duplicates.
            var filterWordList = new TransformBlock<string[], string[]>(words =>
            {
                Console.WriteLine("Filtering word list...");

                return words.Where(word => word.Length > 3).OrderBy(word => word)
                   .Distinct().ToArray();
            });

            // Finds all words in the specified collection whose reverse also
            // exists in the collection.
            var findReversedWords = new TransformManyBlock<string[], string>(words =>
            {
                Console.WriteLine("Finding reversed words...");

                // Holds reversed words.
                var reversedWords = new ConcurrentQueue<string>();

                // Add each word in the original collection to the result whose
                // reversed word also exists in the collection.
                Parallel.ForEach(words, word =>
                {
                    // Reverse the work.
                    string reverse = new string(word.Reverse().ToArray());

                    // Enqueue the word if the reversed version also exists
                    // in the collection.
                    if (Array.BinarySearch<string>(words, reverse) >= 0 &&
                        word != reverse)
                    {
                        reversedWords.Enqueue(word);
                    }
                });

                return reversedWords;
            });

            // Prints the provided reversed words to the console.
            var printReversedWords = new ActionBlock<string>(reversedWord =>
            {
                Console.WriteLine("Found reversed words {0}/{1}",
                   reversedWord, new string(reversedWord.Reverse().ToArray()));
            });

            //
            // Connect the dataflow blocks to form a pipeline.
            //

            downloadString.LinkTo(createWordList);
            createWordList.LinkTo(filterWordList);
            filterWordList.LinkTo(findReversedWords);
            findReversedWords.LinkTo(printReversedWords);

            //
            // For each completion task in the pipeline, create a continuation task
            // that marks the next block in the pipeline as completed.
            // A completed dataflow block processes any buffered elements, but does
            // not accept new elements.
            //

            downloadString.Completion.ContinueWith(t =>
            {
                if (t.IsFaulted) ((IDataflowBlock)createWordList).Fault(t.Exception);
                else createWordList.Complete();
            });
            createWordList.Completion.ContinueWith(t =>
            {
                if (t.IsFaulted) ((IDataflowBlock)filterWordList).Fault(t.Exception);
                else filterWordList.Complete();
            });
            filterWordList.Completion.ContinueWith(t =>
            {
                if (t.IsFaulted) ((IDataflowBlock)findReversedWords).Fault(t.Exception);
                else findReversedWords.Complete();
            });
            findReversedWords.Completion.ContinueWith(t =>
            {
                if (t.IsFaulted) ((IDataflowBlock)printReversedWords).Fault(t.Exception);
                else printReversedWords.Complete();
            });

            // Process "The Iliad of Homer" by Homer.
            downloadString.Post("http://www.gutenberg.org/files/6130/6130-0.txt");

            // Mark the head of the pipeline as complete. The continuation tasks
            // propagate completion through the pipeline as each part of the
            // pipeline finishes.
            downloadString.Complete();

            // Wait for the last block in the pipeline to process all messages.
            printReversedWords.Completion.Wait();

            Console.ReadLine();
        }
        public async Task TestAsObservableAndAsObserver_ErrorPropagation()
        {
            // Test that exceptional data flows when exception occurs before and after subscription
            foreach (bool beforeSubscription in DataflowTestHelpers.BooleanValues)
            {
                var tb = new TransformBlock<int, int>(i => {
                    if (i == 42) throw new InvalidOperationException("uh oh");
                    return i;
                });

                if (beforeSubscription)
                {
                    tb.Post(42);
                    await Assert.ThrowsAsync<InvalidOperationException>(async () => await tb.Completion);
                }

                ITargetBlock<int>[] targets = Enumerable.Range(0, 3).Select(_ => new WriteOnceBlock<int>(i => i)).ToArray();
                foreach (var target in targets)
                {
                    tb.AsObservable().Subscribe(target.AsObserver());
                }

                if (!beforeSubscription)
                {
                    tb.Post(42);
                    await Assert.ThrowsAsync<InvalidOperationException>(() => tb.Completion);
                }

                foreach (var target in targets)
                {
                    await Assert.ThrowsAsync<AggregateException>(() => target.Completion);
                }
            }
        }
Пример #60
0
		public void AsyncCancelledTest ()
		{
			var scheduler = new TestScheduler ();
			var block = new TransformBlock<int, int> (
				i =>
				{
					var tcs = new TaskCompletionSource<int> ();
					tcs.SetCanceled ();
					return tcs.Task;
				}, new ExecutionDataflowBlockOptions { TaskScheduler = scheduler });

			Assert.IsTrue (block.Post (1));

			scheduler.ExecuteAll ();

			Assert.IsFalse (block.Completion.Wait (100));
		}