gpt4 book ai didi

c# - LINQ 选择异步方法的模拟

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

假设我有以下示例代码:

private static async Task Main(string[] args)
{
var result = Enumerable.Range(0, 3).Select(x => TestMethod(x)).ToArray();
Console.ReadKey();
}

private static int TestMethod(int param)
{
Console.WriteLine($"{param} before");
Thread.Sleep(50);
Console.WriteLine($"{param} after");
return param;
}

TestMethod 将运行完成 3 次,因此我会看到 3 对 beforeafter:

0 before
0 after
1 before
1 after
2 before
2 after

现在,我需要使 TestMethod 异步:

private static async Task<int> TestMethod(int param)
{
Console.WriteLine($"{param} before");
await Task.Delay(50);
Console.WriteLine($"{param} after");
return param;
}

如何为此异步方法编写类似的 Select 表达式?如果我只使用异步 lambda Enumerable.Range(0, 3).Select(async x => wait TestMethod(x)).ToArray();,那将不起作用,因为它不会' t 等待完成,因此 before 部分将首先被调用:

0 before
1 before
2 before
2 after
0 after
1 after

请注意,我不想并行运行所有 3 个调用 - 我需要它们一个接一个地执行,仅当前一个调用完全完成并返回值时才开始下一个调用。

最佳答案

我经常遇到这个要求,但我不知道 C# 7.2 有任何内置解决方案可以解决这个问题。我通常只是在 foreach 中的每个异步操作上使用 await,但您可以使用扩展方法:

public static class EnumerableExtensions
{
public static async Task<IEnumerable<TResult>> SelectAsync<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, Task<TResult>> asyncSelector)
{
var results = new List<TResult>();
foreach (var item in source)
results.Add(await asyncSelector(item));
return results;
}
}

然后,您可以在 SelectAsync 上调用 await:

static async Task Main(string[] args)
{
var result = (await Enumerable.Range(0, 3).SelectAsync(x => TestMethod(x))).ToArray();
Console.ReadKey();
}

此方法的缺点是 SelectAsync 是急切的,而不是惰性的。 C# 8 promise 引入async streams ,这将允许它再次变得懒惰。

关于c# - LINQ 选择异步方法的模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54853352/

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