public void Start() { var sink = new ActionBlock<PageResultMessage>((Action<PageResultMessage>)Sink); var source = new BufferBlock<GetPageMessage>(); var linkOptions = new DataflowLinkOptions {PropagateCompletion = false}; for (int i = 0; i < 10; i++) { var options = new ExecutionDataflowBlockOptions { BoundedCapacity = 1 }; var worker = new TransformBlock<GetPageMessage, PageResultMessage>( (Func<GetPageMessage, PageResultMessage>)Worker, options); source.LinkTo(worker, linkOptions); worker.LinkTo(sink, linkOptions); } foreach (var url in UrlList.Urls) { source.Post(new GetPageMessage{ Url = url }); } source.Complete(); sink.Completion.Wait(); }
public MessagePipeline() { linkOptions = new DataflowLinkOptions { PropagateCompletion = true }; buildMessage = new TransformBlock<object, Messaging.Message>( x => { Console.WriteLine("buildMessage| message: {0}", x); return new Messaging.Message { Body = x }; }); logMessage = new TransformBlock<Messaging.Message, Messaging.Message> (x => { Console.WriteLine("logMessage| MessageId: {0}. Body: {1}.", x.MessageId, x.Body); return x; }); sendMessage = new TransformBlock<Messaging.Message, Messaging.Message>( x => { Console.WriteLine("sendMessage| MessageId: {0}. Body: {1}.", x.MessageId, x.Body); return x; }); buildMessage.LinkTo(logMessage, linkOptions); logMessage.LinkTo(sendMessage, linkOptions); }
public static void Generate(string root) { Directory.CreateDirectory("docs"); var _executingDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); File.Copy(Path.Combine(_executingDirectory, "Resources", "Nocco.css"), Path.Combine("docs", "nocco.css"), true); File.Copy(Path.Combine(_executingDirectory, "Resources", "prettify.js"), Path.Combine("docs", "prettify.js"), true); var getFiles = DirectoryTraveler.Create(); var readFiles = FileReader.Create(); var redFileBuffer = new BufferBlock<FileContents>(); var parseFiles = FileParser.Create(); var renderCode = CodeRenderer.Create(); var renderDocs = DocRenderer.Create(); var generateHtml = HtmlGenerator.Create(); var persistanceBuffer = new BufferBlock<RenderedFile>(); var persistFile = FilePersister.Create(); var propCompl = new DataflowLinkOptions { PropagateCompletion = true }; getFiles.LinkTo(readFiles, propCompl); readFiles.LinkTo(redFileBuffer, propCompl); redFileBuffer.LinkTo(parseFiles, propCompl); parseFiles.LinkTo(renderCode, propCompl); renderCode.LinkTo(renderDocs, propCompl); renderDocs.LinkTo(generateHtml, propCompl); generateHtml.LinkTo(persistanceBuffer, propCompl); persistanceBuffer.LinkTo(persistFile, propCompl); getFiles.Post(root); getFiles.Complete(); persistanceBuffer.Completion.Wait(); }
/// <summary> /// Links a source and target data flow block without knowing the generic types used. Propagates completion. /// </summary> /// <param name="sourceBlock">The source block.</param> /// <param name="targetBlock">The target block.</param> /// <param name="linkOptions">The dataflowlink options.</param> /// <returns> /// Disposable for unlinking or null if unsuccessful. /// </returns> /// <exception cref="System.InvalidOperationException"></exception> public static IDisposable LinkTo(this IDataflowBlock sourceBlock, IDataflowBlock targetBlock, DataflowLinkOptions linkOptions) { if (sourceBlock == null || targetBlock == null) return null; try { // Using runtime (late) binding because we don't know what the generic types are return ((dynamic)sourceBlock).LinkTo((dynamic)targetBlock, linkOptions); } catch (RuntimeBinderException ex) { // Indicates the objects passed in are not the correct types. throw new InvalidOperationException( string.Format("Unable to link data flow blocks {0} to {1}.", sourceBlock, targetBlock), ex); } }
public void Run() { var propagateCompletion = new DataflowLinkOptions { PropagateCompletion = true }; var csep = new ConcurrentExclusiveSchedulerPair(); var concurrentOptions = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 2, TaskScheduler = csep.ConcurrentScheduler }; var exclusiveOptions = new ExecutionDataflowBlockOptions { TaskScheduler = csep.ExclusiveScheduler }; var concurrent = new ActionBlock<int>(async i => { Console.WriteLine("Concurent print value: {0}", i); await Task.Delay(500); }, concurrentOptions); var exclusive = new ActionBlock<int>(i => { Console.WriteLine("Exclusive print value: {0}", i); Thread.Sleep(750); }, exclusiveOptions); var broadcaster = new BroadcastBlock<int>(i => i); broadcaster.LinkTo(concurrent, propagateCompletion); broadcaster.LinkTo(exclusive, propagateCompletion, i => i % 2 == 0); Enumerable .Range(1, 10) .ToList() .ForEach(i => broadcaster.Post(i)); broadcaster.Complete(); Task.WaitAll(concurrent.Completion, exclusive.Completion); }
public void Run() { Console.WriteLine("Generating first 10 powers of 2."); var bufferBlock = new BufferBlock<int>(); Enumerable.Range(1, 10) .ToList() .ForEach(i => bufferBlock.Post(i)); var transformBlock = new TransformBlock<int, double>(i => { Console.WriteLine("Raising 2 to the power of {0}.", i); if (i == 5) { Console.WriteLine("32 is so mainstream... Throwing exception..."); throw null; } return Math.Pow(2, i); }, new ExecutionDataflowBlockOptions { BoundedCapacity = 1 }); var actionBlock = new ActionBlock<double>(async i => { await Task.Delay(500); Console.WriteLine(i); }, new ExecutionDataflowBlockOptions { BoundedCapacity = 10 }); var completion = actionBlock.Completion.ContinueWith(t => { Console.WriteLine("Processing failed."); Console.WriteLine(t.Exception.Message); }, TaskContinuationOptions.OnlyOnFaulted); var options = new DataflowLinkOptions { PropagateCompletion = true }; bufferBlock.LinkTo(transformBlock, options); transformBlock.LinkTo(actionBlock, options); completion.Wait(); }
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(); }
/// <include file='XmlDocs/CommonXmlDocComments.xml' path='CommonXmlDocComments/Sources/Member[@name="LinkTo"]/*' /> public IDisposable LinkTo(ITargetBlock <T> target, DataflowLinkOptions linkOptions) { return(_source.LinkTo(target, linkOptions)); }
public IDisposable LinkTo(ITargetBlock <Tuple <IList <T1>, IList <T2> > > target, DataflowLinkOptions linkOptions) { return(_source.LinkTo(target, linkOptions)); }
public IDisposable LinkTo(ITargetBlock <Tuple <IList <T1>, IList <T2> > > target, DataflowLinkOptions linkOptions) { return(outgoing.AddTarget(target, linkOptions)); }
/// <summary> /// Create a logging thread to process the logging queue /// </summary> private void CreateLoggingEventQueue() { // We are creating a two-node dataflow graph here. The first node is a buffer, which will hold up to the number of // logging events we have specified as the queueCapacity. The second node is the processor which will actually process each message. // When the capacity of the buffer is reached, further attempts to send messages to it will block. // The reason we can't just set the BoundedCapacity on the processing block is that ActionBlock has some weird behavior // when the queue capacity is reached. Specifically, it will block new messages from being processed until it has // entirely drained its input queue, as opposed to letting new ones in as old ones are processed. This is logged as // a perf bug (305575) against Dataflow. If they choose to fix it, we can eliminate the buffer node from the graph. var dataBlockOptions = new DataflowBlockOptions { BoundedCapacity = Convert.ToInt32(_queueCapacity) }; _loggingQueue = new BufferBlock<object>(dataBlockOptions); var executionDataBlockOptions = new ExecutionDataflowBlockOptions { BoundedCapacity = 1 }; _loggingQueueProcessor = new ActionBlock<object>(loggingEvent => LoggingEventProcessor(loggingEvent), executionDataBlockOptions); var dataLinkOptions = new DataflowLinkOptions { PropagateCompletion = true }; _loggingQueue.LinkTo(_loggingQueueProcessor, dataLinkOptions); }
public IDisposable LinkTo(ITargetBlock <T> target, DataflowLinkOptions linkOptions) { return(outgoing.AddTarget(target, linkOptions)); }
public IDisposable LinkTo(ITargetBlock <TOutput> target, DataflowLinkOptions linkOptions) => _source.LinkTo(target, linkOptions);