using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Threading.Tasks.Dataflow; namespace Experimentation { public class Line { public string Content { get; set; } public int Number { get; set; } } public static class FileTransformBlock { public static ISourceBlock Create(string file, Func transform) { var block = new TransformBlock( transform, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 2, BoundedCapacity = 128 }); new Thread(() => { var input = block.AsObserver(); try { using (var reader = new StreamReader(file)) { string line; int lineNr = 0; var batch = new List(); while ((line = reader.ReadLine()) != null) input.OnNext(new Line { Content = line, Number = lineNr++ }); input.OnCompleted(); } } catch (Exception ex) { input.OnError(ex); } }).Start(); return block; } public static ISourceBlock> CreateBatch(string file, Func transform) { var block = new TransformBlock, List>( batch => batch.Select(transform).ToList(), new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 8, BoundedCapacity = 128 }); new Thread(() => { var input = block.AsObserver(); try { using (var reader = new StreamReader(file)) { string line; int lineNr = 0; var batch = new List(); while ((line = reader.ReadLine()) != null) { batch.Add(new Line { Content = line, Number = lineNr++ }); if (batch.Count >= 512) { input.OnNext(batch); batch = new List(); } } if (batch.Count > 0) input.OnNext(batch); input.OnCompleted(); } } catch (Exception ex) { input.OnError(ex); } }).Start(); return block; // var order = new TransformBlock, List>(t => t, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 1 }); // block.LinkTo(order, new DataflowLinkOptions { PropagateCompletion = true }); // return order; } public static ISourceBlock> Batch(int n, ISourceBlock source) { var block = new BatchBlock(n); source.LinkTo(block, new DataflowLinkOptions { PropagateCompletion = true }); return block; } } }