gpt4 book ai didi

c# - IAsyncEnumerable 或 IAsyncEnumerator 的工厂

转载 作者:行者123 更新时间:2023-12-03 21:14:47 26 4
gpt4 key购买 nike

我想知道是否有办法创建 IAsyncEnumerable<T>IAsyncEnumerator<T>通过 Source 对象,而不是像 TaskCompletionSource允许一个人为任务做。特别是TaskCompletionSource可以像任何其他参数一样传递。

也许是这样的:

public class AsyncEnumerables {

public Task HandlerTask { get; set; }

public async Task<string> ParentMethod() {
var source = new AsyncEnumerableSource<int>();
IAsyncEnumerable asyncEnumerable = source.GetAsyncEnumerable();
HandlerTask = Task.Run(() => handleAsyncResultsAsTheyHappen(asyncEnumerable));
int n = await someOtherTask();
source.YieldReturn(n);
var r = await ChildMethod(source);
source.Complete(); // this call would cause the HandlerTask to complete.
return r;
}

private async Task<string> ChildMethod(AsyncEnumerableSource<int> source) {
source.YieldReturn(5);
await SomeOtherCall();
source.YieldReturn(10);
return "hello";
}
}

使用上面的代码, handleAsyncResultsAsTheyHappen任务会看到任何传递给 YieldReturn 的值。所以它会看到 n从上面的代码,以及 510来自 ChildMethod .

最佳答案

如果您可以构建代码以利用 yield return,情况会好得多。和 await foreach .例如,这段代码几乎做了同样的事情:

public async Task Consume()
{
var source = ParentMethod();
HandlerTask = Task.Run(async () => { await foreach (var item in source) { Console.WriteLine(item); } });
}

public async IAsyncEnumerable<int> ParentMethod()
{
await Task.Yield();
yield return 13;
await foreach (var item in ChildMethod())
yield return item;
}

private async IAsyncEnumerable<int> ChildMethod()
{
yield return 5;
await Task.Yield();
yield return 10;
}

然而,如果你真的需要一个“异步可枚举源”,你首先需要认识到一件事。 TaskCompletionSource<T>保存结果,即 T (或异常(exception))。它充当一个容器。可以在等待任务之前设置结果。这与“异步可枚举源”相同 - 在从中取出任何项目之前,您需要它能够保存结果。 “异步可枚举源”需要保存多个结果 - 在这种情况下,是一个集合。

所以你实际上要求的是“一个可以作为异步枚举使用的集合”。这里有几种可能性,但我推荐的是 Channel :
public async Task<string> ParentMethod()
{
var source = Channel.CreateUnbounded<int>();
var sourceWriter = source.Writer;
IAsyncEnumerable<int> asyncEnumerable = source.Reader.ReadAllAsync();
HandlerTask = Task.Run(async () => { await foreach (var item in asyncEnumerable) Console.WriteLine(item); });
await Task.Yield();
await sourceWriter.WriteAsync(13);
var r = await ChildMethod(sourceWriter);
sourceWriter.Complete();
return r;
}

private async Task<string> ChildMethod(ChannelWriter<int> sourceWriter)
{
await sourceWriter.WriteAsync(5);
await Task.Yield();
await sourceWriter.WriteAsync(10);
return "hello";
}

关于c# - IAsyncEnumerable 或 IAsyncEnumerator 的工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61540896/

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