public void SelectSendAndReceiveSendReady() { var c1 = new Chan <int>(); var c2 = new Chan <int>(); var t1 = new Thread(() => c1.Send(1)); t1.IsBackground = true; var list = new List <int>(); var t2 = new Thread(() => { Thread.Sleep(50); list.Add(c2.Receive()); }); t2.IsBackground = true; t1.Start(); t2.Start(); Select .CaseReceive(c1, list.Add) .CaseSend(c2, 2, () => { }) .NoDefault(); Assert.AreEqual(1, list.Count, "list.Count"); Assert.AreEqual(1, list[0], "list[0]"); }
private void BenchmarkTcp(int parallel) { string topicName = "test_benchmark_" + DateTime.Now.UnixNano(); try { const int benchmarkNum = 30000; byte[] body = new byte[512]; var p = new Producer("127.0.0.1:4150"); p.Connect(); var startCh = new Chan <bool>(); var wg = new WaitGroup(); for (int j = 0; j < parallel; j++) { wg.Add(1); GoFunc.Run(() => { startCh.Receive(); for (int i = 0; i < benchmarkNum / parallel; i++) { p.Publish(topicName, body); } wg.Done(); }, "ProducerBenchmarkTcpTest: sendLoop"); } var stopwatch = Stopwatch.StartNew(); startCh.Close(); var done = new Chan <bool>(); GoFunc.Run(() => { wg.Wait(); done.Send(true); }, "waiter and done sender"); bool finished = false; Select .CaseReceive(done, b => finished = b) .CaseReceive(Time.After(TimeSpan.FromSeconds(10)), b => finished = false) .NoDefault(); stopwatch.Stop(); if (!finished) { Assert.Fail("timeout"); } Console.WriteLine(string.Format("{0:#,0} sent in {1:mm\\:ss\\.fff}; Avg: {2:#,0} msgs/s; Threads: {3}", benchmarkNum, stopwatch.Elapsed, benchmarkNum / stopwatch.Elapsed.TotalSeconds, parallel)); p.Stop(); } finally { _nsqdHttpClient.DeleteTopic(topicName); _nsqLookupdHttpClient.DeleteTopic(topicName); } }
public void SelectSendsOnly() { var c1 = new Chan <int>(); var c2 = new Chan <int>(); var t1 = new Thread(() => { Thread.Sleep(1000); c1.Receive(); }); t1.IsBackground = true; var t2 = new Thread(() => c2.Receive()); t2.IsBackground = true; var list = new List <int>(); t1.Start(); t2.Start(); Select .CaseSend(c1, 1, () => list.Add(1)) .CaseSend(c2, 2, () => list.Add(2)) .NoDefault(); Assert.AreEqual(1, list.Count, "list.Count"); Assert.AreEqual(2, list[0], "list[0]"); }
/// <summary> /// <para>Publishes a message <paramref name="body"/> to the specified <paramref name="topic"/> /// but does not wait for the response from nsqd.</para> /// /// <para>When the Producer eventually receives the response from nsqd, the Task will return a /// <see cref="ProducerResponse"/> instance with the supplied <paramref name="args"/> and the response error if /// present.</para> /// </summary> /// <param name="topic">The topic to publish to.</param> /// <param name="body">The message body.</param> /// <param name="args">A variable-length parameters list containing arguments. These arguments will be returned on /// <see cref="ProducerResponse.Args"/>. /// </param> /// <returns>A Task<ProducerResponse> which can be awaited.</returns> public Task <ProducerResponse> PublishAsync(string topic, byte[] body, params object[] args) { var doneChan = new Chan <ProducerResponse>(); sendCommandAsync(Command.Publish(topic, body), doneChan, args); return(Task.Factory.StartNew(() => doneChan.Receive())); }
public void BufferedChannelsDontBlock() { var c = new Chan<int>(1); c.Send(2); int actual = c.Receive(); Assert.AreEqual(2, actual); }
/// <summary> /// <para>Publishes a collection of message <paramref name="bodies"/> to the specified <paramref name="topic"/> /// but does not wait for the response from nsqd.</para> /// /// <para>When the Producer eventually receives the response from nsqd, the Task will return a /// <see cref="ProducerResponse"/> instance with the supplied <paramref name="args"/> and the response error if /// present.</para> /// </summary> /// <param name="topic">The topic to publish to.</param> /// <param name="bodies">The collection of message bodies.</param> /// <param name="args">A variable-length parameters list containing arguments. These arguments will be returned on /// <see cref="ProducerResponse.Args"/>. /// </param> /// <returns>A Task<ProducerResponse> which can be awaited.</returns> public Task <ProducerResponse> MultiPublishAsync(string topic, IEnumerable <byte[]> bodies, params object[] args) { var doneChan = new Chan <ProducerResponse>(); var cmd = Command.MultiPublish(topic, bodies); sendCommandAsync(cmd, doneChan, args); return(Task.Factory.StartNew(() => doneChan.Receive())); }
public void BufferedChannel1() { var ch = new Chan <int>(3); Task t = Task.Run(() => { Thread.Sleep(10); ch.Send(1); ch.Send(2); ch.Send(3); }); var result = ch.Receive(); Assert.AreEqual(result, 1); result = ch.Receive(); Assert.AreEqual(result, 2); result = ch.Receive(); Assert.AreEqual(result, 3); }
public void BufferedChannelsDontBlock() { var c = new Chan <int>(1); c.Send(2); var actual = c.Receive(); Assert.AreEqual(2, actual); }
public void ReceiveOnClosedChannelReturnsDefault() { var c = new Chan <int>(); c.Close(); var val = c.Receive(); Assert.AreEqual(default(int), val); }
public void PrimeSieve() { var generate = new Action <Chan <int> >(cgen => { while (true) { for (var i = 2; ; i++) { cgen.Send(i); } } // ReSharper disable once FunctionNeverReturns }); var filter = new Action <Chan <int>, Chan <int>, int>((cin, cout, prime) => { while (true) { var i = cin.Receive(); if (i % prime != 0) { cout.Send(i); } } // ReSharper disable once FunctionNeverReturns }); var ch = new Chan <int>(); var generateCh = ch; var threadGenerate = new Thread(() => generate(generateCh)); threadGenerate.IsBackground = true; threadGenerate.Start(); var list = new List <int>(); for (var i = 0; i < 10; i++) { var prime = ch.Receive(); list.Add(prime); var ch0 = ch; var ch1 = new Chan <int>(); var threadFilter = new Thread(() => filter(ch0, ch1, prime)); threadFilter.IsBackground = true; threadFilter.Start(); ch = ch1; } AssertHelper.AreEqual(new[] { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 }, list); }
public void UnbufferChannel2() { var ch = new Chan <MyClass>(); Task t = Task.Run(() => { Thread.Sleep(10); var s = new MyClass(); s.Name = "RocketMQ"; ch.Send(s); }); var result = ch.Receive(); Assert.AreEqual(result.Name, "RocketMQ"); }
public void SelectSendAndReceiveReceiveReady() { var listLocker = new object(); var c1 = new Chan <int>(); var c2 = new Chan <int>(); var t1 = new Thread(() => { Thread.Sleep(150); c1.Send(1); }); t1.IsBackground = true; var list = new List <int>(); var t2 = new Thread(() => { var val = c2.Receive(); lock (listLocker) { list.Add(val); } }); t2.IsBackground = true; t1.Start(); t2.Start(); Select .CaseReceive(c1, o => { lock (listLocker) { list.Add(o); } }) .CaseSend(c2, 2) .NoDefault(); Thread.Sleep(20); lock (listLocker) { Assert.AreEqual(1, list.Count, "list.Count"); Assert.AreEqual(2, list[0], "list[0]"); } }
private void BenchmarkHttp(int parallel) { string topicName = "test_benchmark_" + DateTime.Now.UnixNano(); try { const int benchmarkNum = 30000; byte[] body = new byte[512]; var startCh = new Chan <bool>(); var wg = new WaitGroup(); for (int j = 0; j < parallel; j++) { wg.Add(1); GoFunc.Run(() => { startCh.Receive(); for (int i = 0; i < benchmarkNum / parallel; i++) { _nsqdHttpClient.Publish(topicName, body); } wg.Done(); }, "ProducerBenchmarkHttpTest: sendLoop"); } var stopwatch = Stopwatch.StartNew(); startCh.Close(); wg.Wait(); stopwatch.Stop(); Console.WriteLine(string.Format("{0:#,0} sent in {1:mm\\:ss\\.fff}; Avg: {2:#,0} msgs/s; Threads: {3}", benchmarkNum, stopwatch.Elapsed, benchmarkNum / stopwatch.Elapsed.TotalSeconds, parallel)); } finally { _nsqdHttpClient.DeleteTopic(topicName); _nsqLookupdHttpClient.DeleteTopic(topicName); } }
private void sendCommand(Command cmd) { var doneChan = new Chan <ProducerResponse>(); try { sendCommandAsync(cmd, doneChan); } catch (Exception) { doneChan.Close(); throw; } var t = doneChan.Receive(); if (t.Error != null) { throw t.Error; } }
public void MultipleNumberGenerators() { var c = new Chan <int>(); for (var i = 0; i < 10; i++) { var localNum = i; var t = new Thread(() => c.Send(localNum)); t.IsBackground = true; t.Start(); } var list = new List <int>(); for (var i = 0; i < 10; i++) { list.Add(c.Receive()); } list.Sort(); AssertHelper.AreEqual(new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, list); }
private void handle(TcpClient conn, EndPoint remoteEndPoint) { int idx = 0; Console.WriteLine("[{0}] TCP: new client({1})", DateTime.Now.Formatted(), remoteEndPoint); using (var rdr = new BinaryReader(conn.GetStream())) using (var connw = new BinaryWriter(conn.GetStream())) { rdr.ReadBytes(4); var readChan = new Chan<byte[]>(); var readDoneChan = new Chan<int>(); var scriptTime = Time.After(script[0].delay); GoFunc.Run(() => { while (true) { try { var line = ReadBytes(rdr, (byte)'\n'); // trim the '\n' line = line.Take(line.Length - 1).ToArray(); readChan.Send(line); readDoneChan.Receive(); } catch { return; } } }, "mockNSQD:ReadBytes"); int rdyCount = 0; bool doLoop = true; while (doLoop && idx < script.Length) { Select .CaseReceive(readChan, line => { string strLine = Encoding.UTF8.GetString(line); Console.WriteLine("[{0}] mock: '{1}'", DateTime.Now.Formatted(), strLine); got.Add(line); gotTime.Add(DateTime.Now); var args = strLine.Split(' '); switch (args[0]) { case "IDENTIFY": try { byte[] l = rdr.ReadBytes(4); int size = Binary.BigEndian.Int32(l); byte[] b = rdr.ReadBytes(size); Console.WriteLine(string.Format("[{0}] {1}", DateTime.Now.Formatted(), Encoding.UTF8.GetString(b))); } catch (Exception ex) { Console.WriteLine(ex.ToString()); doLoop = false; throw; } break; case "RDY": int rdy = int.Parse(args[1]); rdyCount = rdy; break; } readDoneChan.Send(1); }) .CaseReceive(scriptTime, o => { bool doWrite = true; var inst = script[idx]; if (inst.body.SequenceEqual(Encoding.UTF8.GetBytes("exit"))) { doLoop = false; doWrite = false; } if (inst.frameType == (int)FrameType.Message) { if (rdyCount == 0) { Console.WriteLine("[{0}] !!! RDY == 0", DateTime.Now.Formatted()); scriptTime = Time.After(script[idx + 1].delay); doWrite = false; } else { rdyCount--; } } if (doWrite) { try { connw.Write(framedResponse(inst.frameType, inst.body)); scriptTime = Time.After(script[idx + 1].delay); idx++; } catch (Exception ex) { Console.WriteLine(ex.ToString()); doLoop = false; } } }) .NoDefault(); } } tcpListener.Stop(); conn.Close(); }
public void SelectSendsOnly() { var c1 = new Chan<int>(); var c2 = new Chan<int>(); var t1 = new Thread(() => { Thread.Sleep(1000); c1.Receive(); }); t1.IsBackground = true; var t2 = new Thread(() => c2.Receive()); t2.IsBackground = true; var list = new List<int>(); t1.Start(); t2.Start(); Select .CaseSend(c1, 1, () => list.Add(1)) .CaseSend(c2, 2, () => list.Add(2)) .NoDefault(); Assert.AreEqual(1, list.Count, "list.Count"); Assert.AreEqual(2, list[0], "list[0]"); }
public void SelectSendAndReceiveSendReady() { var c1 = new Chan<int>(); var c2 = new Chan<int>(); var t1 = new Thread(() => c1.Send(1)); t1.IsBackground = true; var list = new List<int>(); var t2 = new Thread(() => { Thread.Sleep(50); list.Add(c2.Receive()); }); t2.IsBackground = true; t1.Start(); t2.Start(); Select .CaseReceive(c1, list.Add) .CaseSend(c2, 2, () => { }) .NoDefault(); Assert.AreEqual(1, list.Count, "list.Count"); Assert.AreEqual(1, list[0], "list[0]"); }
public void SelectSendAndReceiveReceiveReady() { object listLocker = new object(); var c1 = new Chan<int>(); var c2 = new Chan<int>(); var t1 = new Thread(() => { Thread.Sleep(150); c1.Send(1); }); t1.IsBackground = true; var list = new List<int>(); var t2 = new Thread(() => { var val = c2.Receive(); lock (listLocker) { list.Add(val); } }); t2.IsBackground = true; t1.Start(); t2.Start(); Select .CaseReceive(c1, func: o => { lock (listLocker) { list.Add(o); } }) .CaseSend(c2, message: 2) .NoDefault(); Thread.Sleep(20); lock (listLocker) { Assert.AreEqual(1, list.Count, "list.Count"); Assert.AreEqual(2, list[0], "list[0]"); } }
public void ReceiveOnClosedChannelReturnsDefault() { var c = new Chan<int>(); c.Close(); int val = c.Receive(); Assert.AreEqual(default(int), val); }
public void PrimeSieve() { var generate = new Action<Chan<int>>(cgen => { while (true) { for (int i = 2; ; i++) { cgen.Send(i); } } // ReSharper disable once FunctionNeverReturns }); var filter = new Action<Chan<int>, Chan<int>, int>((cin, cout, prime) => { while (true) { var i = cin.Receive(); if (i % prime != 0) { cout.Send(i); } } // ReSharper disable once FunctionNeverReturns }); var ch = new Chan<int>(); Chan<int> generateCh = ch; var threadGenerate = new Thread(() => generate(generateCh)); threadGenerate.IsBackground = true; threadGenerate.Start(); var list = new List<int>(); for (int i = 0; i < 10; i++) { int prime = ch.Receive(); list.Add(prime); var ch0 = ch; var ch1 = new Chan<int>(); var threadFilter = new Thread(() => filter(ch0, ch1, prime)); threadFilter.IsBackground = true; threadFilter.Start(); ch = ch1; } Assert.AreEqual(new[] { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 }, list); }
public void MultiThreadedSelectTestWithoutDefer() { var c1 = new Chan<int>(); var c2 = new Chan<int>(); var done = new Chan<bool>(); var start = new Chan<bool>(); int c1Count = 0; int c2Count = 0; int count = 0; int totalReceived = 0; Action receive = () => { start.Receive(); int val1 = 0; int val2 = 0; bool doLoop = true; while (doLoop) { val1 = 0; val2 = 0; Select .CaseReceive(c1, i => val1 = i) .CaseReceive(c2, i => val2 = i) .CaseReceive(done, b => doLoop = false) .NoDefault(); if (doLoop) { Assert.IsTrue(val1 == 0 || val2 == 0, "val1 == 0 || val2 == 0"); Assert.IsTrue(val1 == 1 || val2 == 2, "val1 == 1 || val2 == 2"); } Interlocked.Increment(ref totalReceived); } }; Action send = () => { start.Receive(); while (count < 10000) { Interlocked.Increment(ref count); Select .CaseSend(c1, 1, () => Interlocked.Increment(ref c1Count)) .CaseSend(c2, 2, () => Interlocked.Increment(ref c2Count)) .NoDefault(); Select .CaseSend(c2, 2, () => Interlocked.Increment(ref c2Count)) .CaseSend(c1, 1, () => Interlocked.Increment(ref c1Count)) .NoDefault(); } done.Close(); }; for (int i = 0; i < 8; i++) { GoFunc.Run(receive); GoFunc.Run(send); } start.Close(); done.Receive(); Assert.GreaterOrEqual(count, 10000); Assert.Greater(totalReceived, 19900); }
public void MultipleNumberGenerators() { var c = new Chan<int>(); for (int i = 0; i < 10; i++) { int localNum = i; var t = new Thread(() => c.Send(localNum)); t.IsBackground = true; t.Start(); } var list = new List<int>(); for (int i = 0; i < 10; i++) { list.Add(c.Receive()); } list.Sort(); Assert.AreEqual(new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, list); }
public void MultiThreadedSelectTestWithoutDefer() { var c1 = new Chan <int>(); var c2 = new Chan <int>(); var done = new Chan <bool>(); var start = new Chan <bool>(); var c1Count = 0; var c2Count = 0; var count = 0; var totalReceived = 0; Action receive = () => { start.Receive(); var val1 = 0; var val2 = 0; var doLoop = true; while (doLoop) { val1 = 0; val2 = 0; Select .CaseReceive(c1, i => val1 = i) .CaseReceive(c2, i => val2 = i) .CaseReceive(done, b => doLoop = false) .NoDefault(); if (doLoop) { Assert.IsTrue(val1 == 0 || val2 == 0, "val1 == 0 || val2 == 0"); Assert.IsTrue(val1 == 1 || val2 == 2, "val1 == 1 || val2 == 2"); } Interlocked.Increment(ref totalReceived); } }; Action send = () => { start.Receive(); while (count < 10000) { Interlocked.Increment(ref count); Select .CaseSend(c1, 1, () => Interlocked.Increment(ref c1Count)) .CaseSend(c2, 2, () => Interlocked.Increment(ref c2Count)) .NoDefault(); Select .CaseSend(c2, 2, () => Interlocked.Increment(ref c2Count)) .CaseSend(c1, 1, () => Interlocked.Increment(ref c1Count)) .NoDefault(); } done.Close(); }; for (var i = 0; i < 8; i++) { GoFunc.Run(receive, "receiver"); GoFunc.Run(send, "sender"); } start.Close(); done.Receive(); Assert.IsTrue(count >= 10000); Assert.IsTrue(totalReceived > 19900); }
private void BenchmarkHttp(int parallel) { string topicName = "test_benchmark_" + DateTime.Now.UnixNano(); try { const int benchmarkNum = 30000; byte[] body = new byte[512]; var startCh = new Chan<bool>(); var wg = new WaitGroup(); for (int j = 0; j < parallel; j++) { wg.Add(1); GoFunc.Run(() => { startCh.Receive(); for (int i = 0; i < benchmarkNum / parallel; i++) { _nsqdHttpClient.Publish(topicName, body); } wg.Done(); }, "ProducerBenchmarkHttpTest: sendLoop"); } var stopwatch = Stopwatch.StartNew(); startCh.Close(); wg.Wait(); stopwatch.Stop(); Console.WriteLine(string.Format("{0:#,0} sent in {1:mm\\:ss\\.fff}; Avg: {2:#,0} msgs/s; Threads: {3}", benchmarkNum, stopwatch.Elapsed, benchmarkNum / stopwatch.Elapsed.TotalSeconds, parallel)); } finally { _nsqdHttpClient.DeleteTopic(topicName); _nsqLookupdHttpClient.DeleteTopic(topicName); } }
private void BenchmarkTcp(int parallel) { string topicName = "test_benchmark_" + DateTime.Now.UnixNano(); try { const int benchmarkNum = 30000; byte[] body = new byte[512]; var p = new Producer("127.0.0.1:4150"); p.Connect(); var startCh = new Chan<bool>(); var wg = new WaitGroup(); for (int j = 0; j < parallel; j++) { wg.Add(1); //int localj = j; GoFunc.Run(() => { startCh.Receive(); for (int i = 0; i < benchmarkNum / parallel; i++) { //if (i%10 == 0) //{ // Debug.WriteLine(string.Format("{0}: {1}/{2}", localj, i, benchmarkNum/parallel)); //} p.Publish(topicName, body); } wg.Done(); }, "ProducerBenchmarkTcpTest: sendLoop"); } var stopwatch = Stopwatch.StartNew(); startCh.Close(); var done = new Chan<bool>(); GoFunc.Run(() => { wg.Wait(); done.Send(true); }); bool finished = false; Select .CaseReceive(done, b => finished = b) .CaseReceive(Time.After(TimeSpan.FromSeconds(10)), b => finished = false) .NoDefault(); stopwatch.Stop(); if (!finished) { Assert.Fail("timeout"); } Console.WriteLine(string.Format("{0:#,0} sent in {1:mm\\:ss\\.fff}; Avg: {2:#,0} msgs/s; Threads: {3}", benchmarkNum, stopwatch.Elapsed, benchmarkNum / stopwatch.Elapsed.TotalSeconds, parallel)); } finally { _nsqdHttpClient.DeleteTopic(topicName); _nsqLookupdHttpClient.DeleteTopic(topicName); } }
private void handle(TcpClient conn, EndPoint remoteEndPoint) { int idx = 0; Console.WriteLine("[{0}] TCP: new client({1})", DateTime.Now.Formatted(), remoteEndPoint); using (var rdr = new BinaryReader(conn.GetStream())) using (var connw = new BinaryWriter(conn.GetStream())) { rdr.ReadBytes(4); var readChan = new Chan <byte[]>(); var readDoneChan = new Chan <int>(); var scriptTime = Time.After(script[0].delay); GoFunc.Run(() => { while (true) { try { var line = ReadBytes(rdr, (byte)'\n'); // trim the '\n' line = line.Take(line.Length - 1).ToArray(); readChan.Send(line); readDoneChan.Receive(); } catch { return; } } }, "mockNSQD:ReadBytes"); int rdyCount = 0; bool doLoop = true; while (doLoop && idx < script.Length) { Select .CaseReceive(readChan, line => { string strLine = Encoding.UTF8.GetString(line); Console.WriteLine("[{0}] mock: '{1}'", DateTime.Now.Formatted(), strLine); got.Add(line); gotTime.Add(DateTime.Now); var args = strLine.Split(' '); switch (args[0]) { case "IDENTIFY": try { byte[] l = rdr.ReadBytes(4); int size = Binary.BigEndian.Int32(l); byte[] b = rdr.ReadBytes(size); Console.WriteLine(string.Format("[{0}] {1}", DateTime.Now.Formatted(), Encoding.UTF8.GetString(b))); } catch (Exception ex) { Console.WriteLine(ex.ToString()); doLoop = false; throw; } break; case "RDY": int rdy = int.Parse(args[1]); rdyCount = rdy; break; } readDoneChan.Send(1); }) .CaseReceive(scriptTime, o => { bool doWrite = true; var inst = script[idx]; if (inst.body.SequenceEqual(Encoding.UTF8.GetBytes("exit"))) { doLoop = false; doWrite = false; } if (inst.frameType == (int)FrameType.Message) { if (rdyCount == 0) { Console.WriteLine("[{0}] !!! RDY == 0", DateTime.Now.Formatted()); scriptTime = Time.After(script[idx + 1].delay); doWrite = false; } else { rdyCount--; } } if (doWrite) { try { connw.Write(framedResponse(inst.frameType, inst.body)); scriptTime = Time.After(script[idx + 1].delay); idx++; } catch (Exception ex) { Console.WriteLine(ex.ToString()); doLoop = false; } } }) .NoDefault(); } } tcpListener.Stop(); conn.Close(); }
public void MultiThreadedSelectTestWithDefer() { var c1 = new Chan <int>(); var c2 = new Chan <int>(); var done = new Chan <bool>(); var start = new Chan <bool>(); int c1Count = 0; int c2Count = 0; int count = 0; int totalReceived = 0; Action receive = () => { start.Receive(); int val1 = 0; int val2 = 0; bool doLoop = true; var select = Select .CaseReceive(c1, i => val1 = i) .CaseReceive(c2, i => val2 = i) .CaseReceive(done, b => doLoop = false) .NoDefault(defer: true); while (doLoop) { val1 = 0; val2 = 0; select.Execute(); if (doLoop) { Assert.IsTrue(val1 == 0 || val2 == 0, "val1 == 0 || val2 == 0"); Assert.IsTrue(val1 == 1 || val2 == 2, "val1 == 1 || val2 == 2"); } Interlocked.Increment(ref totalReceived); } }; Action send = () => { start.Receive(); var select = Select .CaseSend(c1, 1, () => Interlocked.Increment(ref c1Count)) .CaseSend(c2, 2, () => Interlocked.Increment(ref c2Count)) .NoDefault(defer: true); while (count < 30000) { Interlocked.Increment(ref count); select.Execute(); } done.Close(); }; for (int i = 0; i < 8; i++) { GoFunc.Run(receive, "receiver"); GoFunc.Run(send, "sender"); } start.Close(); done.Receive(); Assert.GreaterOrEqual(count, 30000); Assert.Greater(totalReceived, 29900); }