static void Main(string[] args) { var buffer = new BufferBlock <int>(); buffer.Post(1); buffer.Post(2); buffer.Post(3); Console.WriteLine("buffer: " + buffer.Receive()); Console.WriteLine("buffer: " + buffer.Receive()); Console.WriteLine("buffer: " + buffer.Receive()); var broadcast = new BroadcastBlock <int>(i => i); broadcast.Post(1); Console.WriteLine("broadcast: " + broadcast.Receive()); Console.WriteLine("broadcast: " + broadcast.Receive()); Console.WriteLine("broadcast: " + broadcast.Receive()); var writeOnce = new WriteOnceBlock <int>(i => i); writeOnce.Post(1); writeOnce.Post(2); writeOnce.Post(3); Console.WriteLine("write-once: " + writeOnce.Receive()); }
private void LastMessageDublicate_ThrowTimeout() { var nmsProtocol = _stack.GetCodec <NmsCodec>().Protocol; var options = new NibusOptions(); NmsMessage lastMessage; nmsProtocol.IncomingMessages.TryReceive(null, out lastMessage); var query = new NmsRead(Destanation, 2); nmsProtocol.OutgoingMessages.Post(query); var wob = new WriteOnceBlock <NmsMessage>(m => m); NmsMessage response, response2; using (nmsProtocol.IncomingMessages.LinkTo( wob, m => !ReferenceEquals(m, lastMessage) && m.IsResponse && m.ServiceType == query.ServiceType && m.Id == query.Id)) { response = wob.Receive(options.Timeout); } nmsProtocol.IncomingMessages.TryReceive(null, out lastMessage); Assert.That(lastMessage, Is.EqualTo(response)); var wob2 = new WriteOnceBlock <NmsMessage>(m => m); using (nmsProtocol.IncomingMessages.LinkTo( wob2, m => !ReferenceEquals(m, lastMessage) && m.IsResponse && m.ServiceType == query.ServiceType && m.Id == query.Id)) { response2 = wob2.Receive(options.Timeout); } }
public void Run() { // Example 1: // ____________________________________________ // Create a WriteOnceBlock<string> object. var writeOnceBlock = new WriteOnceBlock <string>(null); // Post several messages to the block in parallel. The first // message to be received is written to the block. // Subsequent messages are discarded. Parallel.Invoke( () => writeOnceBlock.Post("Message 1"), () => writeOnceBlock.Post("Message 2"), () => writeOnceBlock.Post("Message 3")); // Receive the message from the block. Console.WriteLine(writeOnceBlock.Receive()); /* Sample output: * Message 2 */ // Example 2 // ________________________________________________ // 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(); /* Sample output: * The solution is 53. */ }
public static T RecieveFromAny <T>(params ISourceBlock <T>[] sources) { var writeOnceBlock = new WriteOnceBlock <T>(e => e); foreach (var source in sources) { source.LinkTo(writeOnceBlock, new DataflowLinkOptions { MaxMessages = 1 }); } return(writeOnceBlock.Receive()); }
public override void Run() { WriteOnceBlock <RunModel> writeOnceBlock = new WriteOnceBlock <RunModel>((model) => model); var models = this.CreateCollection(); Parallel.ForEach(models, model => writeOnceBlock.Post(model)); // WriteOnceBlock 只会保留第一个结果,且不限读取次数 Parallel.For(0, 10, (index) => { var model = writeOnceBlock.Receive(); Helper.PrintLine($"{index} {model.Name}"); }); }
public async Task TestReceiveThenPost() { var wob = new WriteOnceBlock <int>(null); var ignored = Task.Run(() => wob.Post(42)); Assert.Equal(expected: 42, actual: wob.Receive()); // this should always pass, but due to race we may not test what we're hoping to await wob.Completion; wob = new WriteOnceBlock <int>(null); Task <int> t = wob.ReceiveAsync(); Assert.False(t.IsCompleted); wob.Post(16); Assert.Equal(expected: 16, actual: await t); }
static public void Run() { var woBlock = new WriteOnceBlock <int>(n => n); for (int i = 0; i < 10; i++) { woBlock.Post(i); } for (int i = 0; i < 10; i++) { Console.WriteLine(woBlock.Receive()); } Console.WriteLine("Done"); }
private static void DataStructure_WriteOnceBlock() { // Create a WriteOnceBlock<string> object. var writeOnceBlock = new WriteOnceBlock <string>(null); // Post several messages to the block in parallel. The first // message to be received is written to the block. // Subsequent messages are discarded. Parallel.Invoke( () => writeOnceBlock.Post("Message 1"), () => writeOnceBlock.Post("Message 2"), () => writeOnceBlock.Post("Message 3")); // Receive the message from the block. Console.WriteLine(writeOnceBlock.Receive()); }
// Receives the value from the first provided source that has // a message. public static T ReceiveFromAny <T>(params ISourceBlock <T>[] sources) { // Create a WriteOnceBlock<T> object and link it to each source block. var writeOnceBlock = new WriteOnceBlock <T>(e => e); foreach (var source in sources) { // Setting MaxMessages to one instructs // the source block to unlink from the WriteOnceBlock<T> object // after offering the WriteOnceBlock<T> object one message. source.LinkTo(writeOnceBlock, new DataflowLinkOptions { MaxMessages = 1 }); } // Return the first value that is offered to the WriteOnceBlock object. return(writeOnceBlock.Receive()); }
private static void TestSync4() { wb.LinkTo(displayBlock); wb.LinkTo(saveBlock); wb.LinkTo(sendBlock); for (int i = 0; i < 4; i++) { wb.Post(i); } wb.Complete(); Console.WriteLine("Post Finished"); wb.Completion.Wait(); Console.WriteLine("Process Finished"); Console.WriteLine("Recive:" + wb.Receive()); }
public void start() { var block = new WriteOnceBlock <int>(x => x); for (int i = 0; i < 10; i++) { if (!block.Post(i)) { Console.WriteLine($"Failed Post - {i}"); } } for (int i = 0; i < 10; i++) { var x = block.Receive(); Console.WriteLine($"Received - {x}"); } }
public void TestLink() { var transformBlock = new TransformWithoutBufferBlock <int, int>(x => x); var target1 = new WriteOnceBlock <int>(null); var target2 = new WriteOnceBlock <int>(null); var target3 = new WriteOnceBlock <int>(null); transformBlock.LinkTo(target1); transformBlock.LinkTo(target2, x => x != 2); transformBlock.LinkTo(target3); transformBlock.Post(1).IsTrue(); transformBlock.Post(2).IsTrue(); transformBlock.Post(3).IsTrue(); target1.Receive(TestUtils.SometimeSoon).Is(1); target2.Receive(TestUtils.SometimeSoon).Is(3); target3.Receive(TestUtils.SometimeSoon).Is(2); }
public void TestWriteOnceCloning() { // Test cloning when a clone function is provided { var writeOnce = new WriteOnceBlock <int>(x => - x); Assert.True(writeOnce.Post(42), "Expected initial post on cloning WriteOnce to succeed"); Assert.False(writeOnce.Post(43), "Expected secondary post on cloning WriteOnce to fail"); Assert.True(writeOnce.Receive() == -42, "Expected Receive'd data to be a clone"); int item; Assert.True(writeOnce.TryReceive(out item) && item == -42, "Expected TryReceive'd data to be a clone"); IList <int> items; Assert.True(((IReceivableSourceBlock <int>)writeOnce).TryReceiveAll(out items) && items.Count == 1 && items[0] == -42, "Expected TryReceiveAll'd data to be a clone"); var ab = new ActionBlock <int>(i => { Assert.True(i == -42, "Expected propagated data to be a clone."); }); writeOnce.LinkTo(ab); ab.Complete(); Assert.True(ab.Completion.Wait(4000), "Expected action block to complete after cloned data flowed to it"); } // Test successful processing when no clone function exists { var data = new object(); var writeOnce = new WriteOnceBlock <object>(null); Assert.True(writeOnce.Post(data), "Expected initial post on non-cloning WriteOnce to succeed"); Assert.False(writeOnce.Post(new object()), "Expected secondary post on non-cloning WriteOnce to fail"); Assert.True(writeOnce.Receive() == data, "Expected Receive'd data to be original data"); object item; Assert.True(writeOnce.TryReceive(out item) && item == data, "Expected TryReceive'd data to be original data"); IList <object> items; Assert.True(((IReceivableSourceBlock <object>)writeOnce).TryReceiveAll(out items) && items.Count == 1 && items[0] == data, "Expected TryReceiveAll'd data to be original data"); var ab = new ActionBlock <object>(i => { Assert.True(i == data, "Expected propagated data to be original data."); }); writeOnce.LinkTo(ab); ab.Complete(); Assert.True(ab.Completion.Wait(4000), "Expected action block to complete after original data flowed to it"); } }
public static void Run() { // Create a WriteOnceBlock<string> object. // Provides a buffer for receiving and storing at most one element in a network of dataflow blocks WriteOnceBlock <string> writeOnceBlock = new WriteOnceBlock <string>(null); // Post several messages to the block in parallel. // The first message to be received is written to the block. // Subsequent messages are discarded. // Executes each of the provided actions, possibly in parallel Parallel.Invoke( () => writeOnceBlock.Post("Message 1. ThreadId: " + Thread.CurrentThread.ManagedThreadId), () => writeOnceBlock.Post("Message 2. ThreadId: " + Thread.CurrentThread.ManagedThreadId), () => writeOnceBlock.Post("Message 3. ThreadId: " + Thread.CurrentThread.ManagedThreadId)); // Receive the message from the block. for (int i = 0; i < 5; i++) { Console.WriteLine(writeOnceBlock.Receive()); } }
static void ShowWriteOnceBlock() { // <snippet3> // Create a WriteOnceBlock<string> object. var writeOnceBlock = new WriteOnceBlock <string>(null); // Post several messages to the block in parallel. The first // message to be received is written to the block. // Subsequent messages are discarded. Parallel.Invoke( () => writeOnceBlock.Post("Message 1"), () => writeOnceBlock.Post("Message 2"), () => writeOnceBlock.Post("Message 3")); // Receive the message from the block. Console.WriteLine(writeOnceBlock.Receive()); /* Sample output: * Message 2 */ // </snippet3> }
public async void TestLink() { var testBlock = new FilterBlock <int>(x => x % 2 != 0); var target1 = new WriteOnceBlock <int>(null); var target2 = new WriteOnceBlock <int>(null); var target3 = new WriteOnceBlock <int>(null); testBlock.LinkTo(target1); testBlock.LinkTo(target2, x => x != 3); testBlock.LinkTo(target3); testBlock.Post(1).IsTrue(); (await testBlock.SendAsync(2).CompleteSoon()).IsTrue(); // drop (await testBlock.SendAsync(3).CompleteSoon()).IsTrue(); (await testBlock.SendAsync(4).CompleteSoon()).IsTrue(); // drop (await testBlock.SendAsync(5).CompleteSoon()).IsTrue(); target1.Receive(TestUtils.SometimeSoon).Is(1); target2.Receive(TestUtils.SometimeSoon).Is(5); target3.Receive(TestUtils.SometimeSoon).Is(3); }
// Demonstrates how to unlink dataflow blocks. // Receives the value from the first provided source that has // a message. /*ISourceBlock<TOutput> Interface Represents a dataflow block that is a source of data*/ public static T ReceiveFromAny <T>(params ISourceBlock <T>[] sources) { // Create a WriteOnceBlock<T> object and link it to each source block. /*Provides a buffer for receiving and storing at most one element * in a network of dataflow blocks*/ WriteOnceBlock <T> writeOnceBlock = new WriteOnceBlock <T>(e => e); foreach (ISourceBlock <T> source in sources) { // Setting MaxMessages to one instructs // the source block to unlink from the WriteOnceBlock<T> object // after offering the WriteOnceBlock<T> object one message. source.LinkTo(writeOnceBlock, new DataflowLinkOptions { MaxMessages = 1 }); } // Return the first value that is offered to the WriteOnceBlock object. T receive = writeOnceBlock.Receive(); return(receive); }
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 TestCloning() { // Test cloning when a clone function is provided { int data = 42; var wob = new WriteOnceBlock <int>(x => - x); Assert.True(wob.Post(data)); Assert.False(wob.Post(data + 1)); for (int i = 0; i < 3; i++) { int item; Assert.True(wob.TryReceive(out item)); Assert.Equal(expected: -data, actual: item); Assert.Equal(expected: -data, actual: wob.Receive()); Assert.Equal(expected: -data, actual: await wob.ReceiveAsync()); IList <int> items; Assert.True(((IReceivableSourceBlock <int>)wob).TryReceiveAll(out items)); Assert.Equal(expected: items.Count, actual: 1); Assert.Equal(expected: -data, actual: items[0]); } int result = 0; var target = new ActionBlock <int>(i => { Assert.Equal(expected: 0, actual: result); result = i; Assert.Equal(expected: -data, actual: i); }); wob.LinkTo(target, new DataflowLinkOptions { PropagateCompletion = true }); await target.Completion; } // Test successful processing when no clone function exists { var data = new object(); var wob = new WriteOnceBlock <object>(null); Assert.True(wob.Post(data)); Assert.False(wob.Post(new object())); object result; for (int i = 0; i < 3; i++) { Assert.True(wob.TryReceive(out result)); Assert.Equal(expected: data, actual: result); Assert.Equal(expected: data, actual: wob.Receive()); Assert.Equal(expected: data, actual: await wob.ReceiveAsync()); IList <object> items; Assert.True(((IReceivableSourceBlock <object>)wob).TryReceiveAll(out items)); Assert.Equal(expected: 1, actual: items.Count); Assert.Equal(expected: data, actual: items[0]); } result = null; var target = new ActionBlock <object>(o => { Assert.Null(result); result = o; Assert.Equal(expected: data, actual: o); }); wob.LinkTo(target, new DataflowLinkOptions { PropagateCompletion = true }); await target.Completion; } }
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 TestWriteOnceCloning() { // Test cloning when a clone function is provided { var writeOnce = new WriteOnceBlock<int>(x => -x); Assert.True(writeOnce.Post(42), "Expected initial post on cloning WriteOnce to succeed"); Assert.False(writeOnce.Post(43), "Expected secondary post on cloning WriteOnce to fail"); Assert.True(writeOnce.Receive() == -42, "Expected Receive'd data to be a clone"); int item; Assert.True(writeOnce.TryReceive(out item) && item == -42, "Expected TryReceive'd data to be a clone"); IList<int> items; Assert.True(((IReceivableSourceBlock<int>)writeOnce).TryReceiveAll(out items) && items.Count == 1 && items[0] == -42, "Expected TryReceiveAll'd data to be a clone"); var ab = new ActionBlock<int>(i => { Assert.True(i == -42, "Expected propagated data to be a clone."); }); writeOnce.LinkTo(ab); ab.Complete(); Assert.True(ab.Completion.Wait(4000), "Expected action block to complete after cloned data flowed to it"); } // Test successful processing when no clone function exists { var data = new object(); var writeOnce = new WriteOnceBlock<object>(null); Assert.True(writeOnce.Post(data), "Expected initial post on non-cloning WriteOnce to succeed"); Assert.False(writeOnce.Post(new object()), "Expected secondary post on non-cloning WriteOnce to fail"); Assert.True(writeOnce.Receive() == data, "Expected Receive'd data to be original data"); object item; Assert.True(writeOnce.TryReceive(out item) && item == data, "Expected TryReceive'd data to be original data"); IList<object> items; Assert.True(((IReceivableSourceBlock<object>)writeOnce).TryReceiveAll(out items) && items.Count == 1 && items[0] == data, "Expected TryReceiveAll'd data to be original data"); var ab = new ActionBlock<object>(i => { Assert.True(i == data, "Expected propagated data to be original data."); }); writeOnce.LinkTo(ab); ab.Complete(); Assert.True(ab.Completion.Wait(4000), "Expected action block to complete after original data flowed to it"); } }
public async Task TestReceiveThenPost() { var wob = new WriteOnceBlock<int>(null); var ignored = Task.Run(() => wob.Post(42)); Assert.Equal(expected: 42, actual: wob.Receive()); // this should always pass, but due to race we may not test what we're hoping to await wob.Completion; wob = new WriteOnceBlock<int>(null); Task<int> t = wob.ReceiveAsync(); Assert.False(t.IsCompleted); wob.Post(16); Assert.Equal(expected: 16, actual: await t); }
public async Task TestCloning() { // Test cloning when a clone function is provided { int data = 42; var wob = new WriteOnceBlock<int>(x => -x); Assert.True(wob.Post(data)); Assert.False(wob.Post(data + 1)); for (int i = 0; i < 3; i++) { int item; Assert.True(wob.TryReceive(out item)); Assert.Equal(expected: -data, actual: item); Assert.Equal(expected: -data, actual: wob.Receive()); Assert.Equal(expected: -data, actual: await wob.ReceiveAsync()); IList<int> items; Assert.True(((IReceivableSourceBlock<int>)wob).TryReceiveAll(out items)); Assert.Equal(expected: items.Count, actual: 1); Assert.Equal(expected: -data, actual: items[0]); } int result = 0; var target = new ActionBlock<int>(i => { Assert.Equal(expected: 0, actual: result); result = i; Assert.Equal(expected: -data, actual: i); }); wob.LinkTo(target, new DataflowLinkOptions { PropagateCompletion = true }); await target.Completion; } // Test successful processing when no clone function exists { var data = new object(); var wob = new WriteOnceBlock<object>(null); Assert.True(wob.Post(data)); Assert.False(wob.Post(new object())); object result; for (int i = 0; i < 3; i++) { Assert.True(wob.TryReceive(out result)); Assert.Equal(expected: data, actual: result); Assert.Equal(expected: data, actual: wob.Receive()); Assert.Equal(expected: data, actual: await wob.ReceiveAsync()); IList<object> items; Assert.True(((IReceivableSourceBlock<object>)wob).TryReceiveAll(out items)); Assert.Equal(expected: 1, actual: items.Count); Assert.Equal(expected: data, actual: items[0]); } result = null; var target = new ActionBlock<object>(o => { Assert.Null(result); result = o; Assert.Equal(expected: data, actual: o); }); wob.LinkTo(target, new DataflowLinkOptions { PropagateCompletion = true }); await target.Completion; } }