BusterWood.Channels是一个在C#上实现的信道的开源库。通过使用这个类库,我们可以在C#语言中实现类似golang和goroutine的信道编程方式。在这里我们介绍3个简单的信道的例子。
通过信道发送消息(https://gobyexample.com/channels):
static void SimpleMessage() { var channel = new Channel<String>(); Task.Run(async () => { await channel.SendAsync("Hello World!"); }); var message = channel.Receive(); Console.WriteLine(message); }
在上面这个例子中,我们在TPL Task中通过信道发送消息。主线程通过Receive接收消息。这里,由于我们的SimpleMessage方法不是一个async方法,我们不能使用ReceiveAsync来接收消息。
static void ChannelSychronization() { var channel = new Channel<bool>(); Task.Run(async () => { Console.Write("Working..."); await Task.Delay(1000); Console.WriteLine("done"); await channel.SendAsync(true); }); channel.ReceiveAsync().Wait(); }
在这个例子中,主线程被ReceiveAsync堵塞,当TPL Task发送消息后,程序才结束。
选择多个信道(https://gobyexample.com/select):
当我们需要从多个信道中接收信息时,我们可以用Select来实现:
static void Select() { var channel1 = new Channel<String>(); var channel2 = new Channel<String>(); Task.Run(async () => { await Task.Delay(1000); await channel1.SendAsync("one"); }); Task.Run(async () => { await Task.Delay(2000); await channel1.SendAsync("two"); }); for (var i = 0; i < 2; i++) { new Select() .OnReceive(channel1, msg1 => { Console.WriteLine("received " + msg1); }) .OnReceive(channel2, msg2 => { Console.WriteLine("received " + msg2); }).ExecuteAsync().Wait(); } }
在上面的例子中,我们通过Select同时从两个信道channel1和channel2接收信息。
这个C#的开源库可以在https://github.com/busterwood/Channels找到代码,nuget文件名为BusterWood.Channels,最新版支持 .net 4.6和 .net core。上面例子的代码可以在https://github.com/mcai4gl2/ChannelExamples找到,例子代码可以在.net core上运行。 这里我们只介绍了几个信道的基本应用,以后我们还会进一步介绍更多的信道的例子。