我试图用基于IAsyncEnumerable的API包装基于事件的异步订阅API。基本上按照以下方针:
async IAsyncEnumerable<string> ReadAll()
{
var reader = new EventBasedReader();
reader.OnRead => (_, args) => yield return e.Message;
reader.Start();
await reader.WaitUntilAllRead();
}但是,这不起作用,因为这是事件处理程序产生的,这是不允许的。还有其他方法可以让它作为IAsyncEnumerable工作吗?
发布于 2020-06-05 11:26:24
包装基于事件的异步订阅API和基于
IAsyncEnumerable的API。
这两者并不是直接兼容的。事件是基于推送的,枚举(包括异步枚举)是基于拉的.
为了跨越这一鸿沟,您需要一个缓冲区--在事件数据被推送到您的时候,但在下游代码提取它之前,需要一个地方来保存它。
我建议使用通道作为缓冲区。如果用例允许,您可以使用一个无限制的通道:
IAsyncEnumerable<string> ReadAll()
{
var reader = new EventBasedReader();
var buffer = Channel.CreateUnbounded<string>();
reader.OnRead = async (_, args) => await buffer.Writer.WriteAsync(e.Message);
reader.Start();
CompleteBufferWhenEventsAreDone();
return buffer.Reader.ReadAllAsync();
async void CompleteBufferWhenEventsAreDone()
{
await reader.WaitUntilAllRead();
buffer.Writer.TryComplete();
}
}https://stackoverflow.com/questions/62214055
复制相似问题