【发布时间】:2021-03-11 09:24:59
【问题描述】:
我有一个工作流程,我尝试执行以下操作:
- 一个接受回调的方法,它在内部产生一个
Stream,并且该方法的调用者可以使用回调以任何他们想要的方式处理Stream - 在一种特殊情况下,调用者使用回调从 Stream 中生成
IAsyncEnumerable。
我在下面创建了一个最小的复制示例:
class Program
{
private static async Task<Stream> GetStream()
{
var text =
@"Multi-line
string";
await Task.Yield();
var bytes = Encoding.UTF8.GetBytes(text);
return new MemoryStream(bytes);
}
private static async Task<T> StreamData<T>(Func<Stream, T> streamAction)
{
await using var stream = await GetStream();
return streamAction(stream);
}
private static async Task StreamData(Func<Stream, Task> streamAction)
{
await using var stream = await GetStream();
await streamAction(stream);
}
private static async IAsyncEnumerable<string> GetTextLinesFromStream(Stream stream)
{
using var reader = new StreamReader(stream);
var line = await reader.ReadLineAsync();
while (line != null)
{
yield return line;
line = await reader.ReadLineAsync();
}
}
private static async Task Test1()
{
async Task GetRecords(Stream str)
{
await foreach(var line in GetTextLinesFromStream(str))
Console.WriteLine(line);
}
await StreamData(GetRecords);
}
private static async Task Test2()
{
await foreach(var line in await StreamData(GetTextLinesFromStream))
Console.WriteLine(line);
}
static async Task Main(string[] args)
{
await Test1();
await Test2();
}
}
在这里,方法Test1 可以正常工作,而Test2 不能,因为Stream is not readable 失败。问题是在第二种情况下,当代码开始处理实际流时,流已经被释放了。
大概这两个例子的区别在于,对于第一个例子,读取流是在一次性stream的上下文中执行的,而在第二个例子中,我们已经退出了。
但是,我认为第二种情况也可能有效 - 至少我觉得它非常符合 C# 习惯。为了让第二个案例也能正常工作,我还有什么遗漏吗?
【问题讨论】:
标签: c# .net asynchronous iasyncenumerable