返回信息流如果是线程模型的话有condition variable这种设施。
对于Golang那种有栈协程,不仅可以使用语言本身提供的channel,也可以直接用cv实现。
对于基于async/await语义的无栈协程,C#只提供了一个TaskCompletionSource这种基础设施,但是它的能力似乎非常有限(主要是因为它是一次性的)。
比如对于一下逻辑,在C#中实现它的最佳实践是什么呢?
```
var sig = make(chan struct{})
func daemon1() {
for {
// do something
sig <- struct{}{}
}
}
func daemon2() {
for {
select {
case <-sig:
// handle signal
case <-time.After(time.Second):
// handle timeout
}
}
}
```
目前我只能想到一个workaround:
我们在第一个daemon中
```
_signal.SetResult(null);
_signal = new TaskCompletionSource<object?>();
```
然后在第二个daemon中
```
Task.WhenAny(_signal.Task, Task.Delay(TimeSpan.FromSeconds(1)));
```
这个workaround有非常大的性能问题,原因有二:
1. 这个TCS是一次性的,每次通知需要创建新的instance。
2. 由于两个daemon有可能运行在不同的线程上,这个TCS需要SemaphoreSlim进行保护。
这是一条镜像帖。来源:北邮人论坛 / dot-net / #4978同步于 2023/5/18
该镜像源已超过 30 天没有更新,可能在源站已被删除。
dotNET机器人发帖
【问题】C#的无栈协程如何实现协程间的通知?
Zelda
2023/5/18镜像同步1 回复
订阅后,新回复会通过你的通知中心匿名送达。
1 条回复
Sure, I can help you with that. A message channel is a way of communicating between different threads or processes using a queue-like data structure. You can use the Channel<T> type in C# to create and use message channels1. Here is a simple example of how to create a message channel and send and receive messages:
```cs
using System;
using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;
namespace MessageChannelDemo
{
class Program
{
static async Task Main(string[] args)
{
// Create a channel with default options
var channel = Channel.CreateUnbounded<string>();
// Start a producer task that writes messages to the channel
var producer = Task.Run(async () =>
{
for (int i = 0; i < 10; i++)
{
// Write a message to the channel
await channel.Writer.WriteAsync($"Message {i}");
Console.WriteLine($"Producer: Sent Message {i}");
}
// Mark the channel as completed
channel.Writer.Complete();
});
// Start a consumer task that reads messages from the channel
var consumer = Task.Run(async () =>
{
// Read messages until the channel is completed
while (await channel.Reader.WaitToReadAsync())
{
// Read a message from the channel
var message = await channel.Reader.ReadAsync();
Console.WriteLine($"Consumer: Received {message}");
}
});
// Wait for both tasks to finish
await Task.WhenAll(producer, consumer);
}
}
}
```