gpt4 book ai didi

c# - 使用 IAsyncEnumerable 读取文本文件

转载 作者:行者123 更新时间:2023-11-30 17:25:13 25 4
gpt4 key购买 nike

我在测试 C# 8.0 功能时遇到了 IAsyncEnumerable。我从 Anthony Chu (https://anthonychu.ca/post/async-streams-dotnet-core-3-iasyncenumerable/) 中找到了很好的例子。它是异步流和 Task<IEnumerable<T>> 的替代品

// Data Access Layer.
public async IAsyncEnumerable<Product> GetAllProducts()
{
Container container = cosmosClient.GetContainer(DatabaseId, ContainerId);
var iterator = container.GetItemQueryIterator<Product>("SELECT * FROM c");
while (iterator.HasMoreResults)
{
foreach (var product in await iterator.ReadNextAsync())
{
yield return product;
}
}
}

// Usage
await foreach (var product in productsRepository.GetAllProducts())
{
Console.WriteLine(product);
}

我想知道这是否可以应用于读取文本文件,如下面逐行读取文件的用法。

foreach (var line in File.ReadLines("Filename"))
{
// ...process line.
}

我真的很想知道如何使用 IAsyncEnumerable<string>() 应用异步到上面的 foreach 循环,以便它在读取时流式传输。

如何实现迭代器以便我可以使用 yield return 逐行读取?

最佳答案

完全一样,但是没有异步工作负载,所以让我们假装

public async IAsyncEnumerable<string> SomeSortOfAwesomeness()
{
foreach (var line in File.ReadLines("Filename.txt"))
{
// simulates an async workload,
// otherwise why would be using IAsyncEnumerable?
// -- added due to popular demand
await Task.Delay(100);
yield return line;
}
}

这只是一个包装的 APM 工作负载,请参阅 Stephen Clearys澄清意见

public static async IAsyncEnumerable<string> SomeSortOfAwesomeness()
{
using StreamReader reader = File.OpenText("Filename.txt");
while(!reader.EndOfStream)
yield return await reader.ReadLineAsync();
}

用法

await foreach(var line in SomeSortOfAwesomeness())
{
Console.WriteLine(line);
}

更新 来自 Stephen Cleary

File.OpenText sadly only allows synchronous I/O; the async APIs are implemented poorly in that scenario. To open a true asynchronous file, you'd need to use a FileStream constructor passing isAsync: true or FileOptions.Asynchronous.

ReadLineAsync 基本上是这段代码的结果,如您所见,它只是包装了 Stream APM BeginEnd 方法

private Task<Int32> BeginEndReadAsync(Byte[] buffer, Int32 offset, Int32 count)
{
return TaskFactory<Int32>.FromAsyncTrim(
this, new ReadWriteParameters { Buffer = buffer, Offset = offset, Count = count },
(stream, args, callback, state) => stream.BeginRead(args.Buffer, args.Offset, args.Count, callback, state), // cached by compiler
(stream, asyncResult) => stream.EndRead(asyncResult)); // cached by compiler
}

关于c# - 使用 IAsyncEnumerable 读取文本文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59043037/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com