public async Task TestWriteOnce() { var bb = new WriteOnceBlock <int>(null); bb.LinkTo(new ActionBlock <int>(i => { Thread.Sleep(1000); Console.WriteLine("Receiver1:" + i); }, new ExecutionDataflowBlockOptions() { BoundedCapacity = 1 })); bb.LinkTo(new ActionBlock <int>(i => { Thread.Sleep(1000); Console.WriteLine("Receiver2:" + i); })); Assert.IsTrue(bb.Post(1)); Assert.IsFalse(bb.Post(2)); Assert.IsFalse(await bb.SendAsync(3)); Assert.IsFalse(bb.Post(4)); Assert.IsFalse(await bb.SendAsync(5)); }
public async Task TestCancellationBeforeAndAfterCtor() { foreach (bool before in DataflowTestHelpers.BooleanValues) { var cts = new CancellationTokenSource(); if (before) { cts.Cancel(); } var wob = new WriteOnceBlock <int>(null, new DataflowBlockOptions { CancellationToken = cts.Token }); if (!before) { cts.Cancel(); } int ignoredValue; IList <int> ignoredValues; Assert.NotNull(wob.LinkTo(DataflowBlock.NullTarget <int>())); Assert.False(wob.Post(42)); Task <bool> sendTask = wob.SendAsync(43); Assert.True(sendTask.IsCompleted); Assert.False(sendTask.Result); Assert.False(wob.TryReceive(out ignoredValue)); Assert.False(((IReceivableSourceBlock <int>)wob).TryReceiveAll(out ignoredValues)); Assert.NotNull(wob.Completion); await Assert.ThrowsAnyAsync <OperationCanceledException>(() => wob.Completion); } }
// Demo of it being used with other blocks. // // Only one push message propagates to the ActionBlock so only one message is received. private static async Task SimpleDemoAsync() { Console.WriteLine("WriteOneBlockDemo has started!"); var options = new DataflowLinkOptions { PropagateCompletion = true }; var writeBlock = new WriteOnceBlock <string>(input => input); var actionBlock = new ActionBlock <string>(Console.WriteLine); writeBlock.LinkTo(actionBlock, options); for (int i = 0; i < 5; i++) { await writeBlock.SendAsync(ProduceTimeData()).ConfigureAwait(false); } writeBlock.Complete(); await actionBlock.Completion.ConfigureAwait(false); Console.WriteLine("Finished!"); Console.ReadKey(); }
public IDisposable LinkTo(ITargetBlock <IEnumerable <T> > target, DataflowLinkOptions linkOptions) { var emitter = new WriteOnceBlock <IEnumerable <T> >(items => items); // When the AccumBlock completes, send all the items to the emitter and complete it. AccumBlock.Completion.ContinueWith(async o => { if (o.IsFaulted) { ((ITargetBlock <IEnumerable <T> >)emitter).Fault(o.Exception); } else { await emitter.SendAsync(Accumulator); emitter.Complete(); Logger.LogTrace("emitter complete."); } }); Completion = emitter.Completion; var disposable = emitter.LinkTo(target, linkOptions); return(disposable); }
public void RunWriteOnceBlockConformanceTests() { bool passed = true, localPassed = true; { // Test posting then receiving localPassed = true; var wob = new WriteOnceBlock <int>(i => i); int successfulPosts = 0; for (int i = 10; i <= 20; i++) { successfulPosts += wob.Post(i) ? 1 : 0; } localPassed |= successfulPosts == 1; localPassed |= wob.Receive() == 10; Console.WriteLine("{0}: Posting then receiving", localPassed ? "Success" : "Failure"); passed &= localPassed; } { // Test receiving then posting localPassed = true; var wob = new WriteOnceBlock <int>(i => i); Task.Factory.StartNew(() => { Task.Delay(1000).Wait(); wob.Post(42); }); localPassed |= wob.Receive() == 42; localPassed |= wob.Post(43) == false; wob.Completion.Wait(); Console.WriteLine("{0}: Receiving then posting", localPassed ? "Success" : "Failure"); passed &= localPassed; } { // Test broadcasting localPassed = true; var wob = new WriteOnceBlock <int>(i => i + 1); var tb1 = new TransformBlock <int, int>(i => i); var tb2 = new TransformBlock <int, int>(i => i); var tb3 = new TransformBlock <int, int>(i => i); wob.LinkTo(tb1); wob.LinkTo(tb2); wob.LinkTo(tb3); wob.Post(42); localPassed |= tb1.Receive() == 43; localPassed |= tb2.Receive() == 43; localPassed |= tb3.Receive() == 43; Console.WriteLine("{0}: Broadcasting", localPassed ? "Success" : "Failure"); passed &= localPassed; } { // Test using a precanceled token localPassed = true; try { var cts = new CancellationTokenSource(); cts.Cancel(); var dbo = new DataflowBlockOptions { CancellationToken = cts.Token }; var wob = new WriteOnceBlock <int>(i => i, dbo); int ignoredValue; IList <int> ignoredValues; localPassed &= wob.LinkTo(new ActionBlock <int>(delegate { })) != null; localPassed &= wob.SendAsync(42).Result == false; localPassed &= ((IReceivableSourceBlock <int>)wob).TryReceiveAll(out ignoredValues) == false; localPassed &= wob.Post(42) == false; localPassed &= wob.TryReceive(out ignoredValue) == false; localPassed &= wob.Completion != null; wob.Complete(); } catch (Exception) { localPassed = false; } Console.WriteLine("{0}: Precanceled tokens work correctly", localPassed ? "Success" : "Failure"); passed &= localPassed; } { // Test using token canceled after construction localPassed = true; try { var cts = new CancellationTokenSource(); var dbo = new DataflowBlockOptions { CancellationToken = cts.Token }; var wob = new WriteOnceBlock <int>(i => i, dbo); cts.Cancel(); int ignoredValue; IList <int> ignoredValues; localPassed &= wob.LinkTo(new ActionBlock <int>(delegate { })) != null; localPassed &= wob.SendAsync(42).Result == false; localPassed &= ((IReceivableSourceBlock <int>)wob).TryReceiveAll(out ignoredValues) == false; localPassed &= wob.Post(42) == false; localPassed &= wob.TryReceive(out ignoredValue) == false; localPassed &= wob.Completion != null; wob.Complete(); } catch (Exception) { localPassed = false; } Console.WriteLine("{0}: Precanceled tokens work correctly", localPassed ? "Success" : "Failure"); passed &= localPassed; } Assert.True(passed, "Test failed."); }
public void RunWriteOnceBlockConformanceTests() { bool passed = true, localPassed = true; { // Test posting then receiving localPassed = true; var wob = new WriteOnceBlock<int>(i => i); int successfulPosts = 0; for (int i = 10; i <= 20; i++) { successfulPosts += wob.Post(i) ? 1 : 0; } localPassed |= successfulPosts == 1; localPassed |= wob.Receive() == 10; Console.WriteLine("{0}: Posting then receiving", localPassed ? "Success" : "Failure"); passed &= localPassed; } { // Test receiving then posting localPassed = true; var wob = new WriteOnceBlock<int>(i => i); Task.Factory.StartNew(() => { Task.Delay(1000).Wait(); wob.Post(42); }); localPassed |= wob.Receive() == 42; localPassed |= wob.Post(43) == false; wob.Completion.Wait(); Console.WriteLine("{0}: Receiving then posting", localPassed ? "Success" : "Failure"); passed &= localPassed; } { // Test broadcasting localPassed = true; var wob = new WriteOnceBlock<int>(i => i + 1); var tb1 = new TransformBlock<int, int>(i => i); var tb2 = new TransformBlock<int, int>(i => i); var tb3 = new TransformBlock<int, int>(i => i); wob.LinkTo(tb1); wob.LinkTo(tb2); wob.LinkTo(tb3); wob.Post(42); localPassed |= tb1.Receive() == 43; localPassed |= tb2.Receive() == 43; localPassed |= tb3.Receive() == 43; Console.WriteLine("{0}: Broadcasting", localPassed ? "Success" : "Failure"); passed &= localPassed; } { // Test using a precanceled token localPassed = true; try { var cts = new CancellationTokenSource(); cts.Cancel(); var dbo = new DataflowBlockOptions { CancellationToken = cts.Token }; var wob = new WriteOnceBlock<int>(i => i, dbo); int ignoredValue; IList<int> ignoredValues; localPassed &= wob.LinkTo(new ActionBlock<int>(delegate { })) != null; localPassed &= wob.SendAsync(42).Result == false; localPassed &= ((IReceivableSourceBlock<int>)wob).TryReceiveAll(out ignoredValues) == false; localPassed &= wob.Post(42) == false; localPassed &= wob.TryReceive(out ignoredValue) == false; localPassed &= wob.Completion != null; wob.Complete(); } catch (Exception) { localPassed = false; } Console.WriteLine("{0}: Precanceled tokens work correctly", localPassed ? "Success" : "Failure"); passed &= localPassed; } { // Test using token canceled after construction localPassed = true; try { var cts = new CancellationTokenSource(); var dbo = new DataflowBlockOptions { CancellationToken = cts.Token }; var wob = new WriteOnceBlock<int>(i => i, dbo); cts.Cancel(); int ignoredValue; IList<int> ignoredValues; localPassed &= wob.LinkTo(new ActionBlock<int>(delegate { })) != null; localPassed &= wob.SendAsync(42).Result == false; localPassed &= ((IReceivableSourceBlock<int>)wob).TryReceiveAll(out ignoredValues) == false; localPassed &= wob.Post(42) == false; localPassed &= wob.TryReceive(out ignoredValue) == false; localPassed &= wob.Completion != null; wob.Complete(); } catch (Exception) { localPassed = false; } Console.WriteLine("{0}: Precanceled tokens work correctly", localPassed ? "Success" : "Failure"); passed &= localPassed; } Assert.True(passed, "Test failed."); }
public async Task TestCancellationBeforeAndAfterCtor() { foreach (bool before in DataflowTestHelpers.BooleanValues) { var cts = new CancellationTokenSource(); if (before) { cts.Cancel(); } var wob = new WriteOnceBlock<int>(null, new DataflowBlockOptions { CancellationToken = cts.Token }); if (!before) { cts.Cancel(); } int ignoredValue; IList<int> ignoredValues; Assert.NotNull(wob.LinkTo(DataflowBlock.NullTarget<int>())); Assert.False(wob.Post(42)); Task<bool> sendTask = wob.SendAsync(43); Assert.True(sendTask.IsCompleted); Assert.False(sendTask.Result); Assert.False(wob.TryReceive(out ignoredValue)); Assert.False(((IReceivableSourceBlock<int>)wob).TryReceiveAll(out ignoredValues)); Assert.NotNull(wob.Completion); await Assert.ThrowsAnyAsync<OperationCanceledException>(() => wob.Completion); } }