猿问

如何在异步 C# 任务中使用 yield

我正在尝试使用 yield 并返回在异步任务中将 X 转换为 Y 的结果。但是,我在选择时遇到错误。错误是:


错误 CS1942 select 子句中的表达式类型不正确。调用“Select”时类型推断失败。


public async Task<Result<dynamic>> GetYAsync(IEnumerable<X> infos)

    {

        return Task.WhenAll(from info in infos.ToArray() select async ()=>

        {

            yield return await new Y(info.Id, "Start");

        });

    }


呼啦一阵风
浏览 225回答 2
2回答

小唯快跑啊

简短回答:您不能使用异步 yield 语句。但在大多数情况下,您不需要。使用LINQ您可以在将所有任务传递到Task.WaitAll. 我简化了您的示例以返回IEnumerable<int>,但这适用于每种类型。public class Program{&nbsp; &nbsp;public static Task<int> X(int x)&nbsp;&nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp;return Task.FromResult(x);&nbsp; &nbsp;}&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;public static async Task<IEnumerable<int>> GetYAsync(IEnumerable<int> infos)&nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp;var res = await Task.WhenAll(infos.Select(info => X(info)));&nbsp; &nbsp; &nbsp; &nbsp;return res;&nbsp; &nbsp;}&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;public static async void Main()&nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp;var test = await GetYAsync(new [] {1, 2, 3});&nbsp; &nbsp; &nbsp; &nbsp;Console.WriteLine(test);&nbsp; &nbsp;}}您的示例还有另一个错误await new Y(...),构造函数不能是异步的,因此我将其替换为异步函数。(正如评论中所暗示的,在技术上可以创建自定义的可等待类型并使用 来创建这种类型new,尽管很少使用),上面的示例infos.Select用于创建挂起任务列表,通过调用函数返回X。然后将等待并返回此任务列表。这workaround应该适合大多数情况。.Net 不支持真正的异步迭代器,例如在 JavaScript 中。更新:目前建议将此功能作为语言建议:Async Streams。所以也许我们将来会看到这一点。更新:如果您需要异步迭代器,目前有几个选项可用:Reactive Stream,RX.Net,它为您提供基于事件的异步可观察流。有异步迭代器或异步可枚举的实现AsyncEnumerable或&nbsp;.Net Async Enumerable

慕村9548890

你不。2019 年的某个时间点,C# 8 提供了异步枚举支持(并且通过 yield 来实现可枚举)。所以,现在的答案很简单,你没有。您收到错误的原因是您也无法返回结果。产量(回报)特定于实现枚举。您的方法签名不匹配。
随时随地看视频慕课网APP
我要回答