IAsyncEnumerable在C#8.0预览中不起作用

Ale*_*lex 8 c# c#-8.0 iasyncenumerable

我正在玩C#8.0预览,无法开始IAsyncEnumerable工作.

我尝试了以下内容

public static async IAsyncEnumerable<int> Get()
{
    for(int i=0; i<10; i++)
    {
        await Task.Delay(100);
        yield return i;
    }
}
Run Code Online (Sandbox Code Playgroud)

我最终使用了一个名为Nuget的包AsyncEnumerator,但是我收到以下错误:

  1. 错误CS1061' IAsyncEnumerable<int>'不包含' '的定义,GetAwaiter并且没有可访问的扩展方法' GetAwaiter' IAsyncEnumerable<int>可以找到类型' ' 的第一个参数(你是否缺少using指令或汇编引用?)
  2. 错误CS1624' Program.Get()' 的主体不能是迭代器块,因为' IAsyncEnumerable<int>'不是迭代器接口类型

我在这里错过了什么?

Pan*_*vos 12

这是在可以通过加入几行代码将被固定在编译器中的错误在这里找到:

namespace System.Threading.Tasks
{
    using System.Runtime.CompilerServices;
    using System.Threading.Tasks.Sources;

    internal struct ManualResetValueTaskSourceLogic<TResult>
    {
        private ManualResetValueTaskSourceCore<TResult> _core;
        public ManualResetValueTaskSourceLogic(IStrongBox<ManualResetValueTaskSourceLogic<TResult>> parent) : this() { }
        public short Version => _core.Version;
        public TResult GetResult(short token) => _core.GetResult(token);
        public ValueTaskSourceStatus GetStatus(short token) => _core.GetStatus(token);
        public void OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) => _core.OnCompleted(continuation, state, token, flags);
        public void Reset() => _core.Reset();
        public void SetResult(TResult result) => _core.SetResult(result);
        public void SetException(Exception error) => _core.SetException(error);
    }
}

namespace System.Runtime.CompilerServices
{
    internal interface IStrongBox<T> { ref T Value { get; } }
}
Run Code Online (Sandbox Code Playgroud)

正如Mads Torgersen在Take C#8中解释的那样:

但是如果你尝试编译并运行它,你会得到一些令人尴尬的错误.那是因为我们搞砸了一些,并没有完全对齐.NET Core 3.0和Visual Studio 2019的预览.具体来说,有一种实现类型,异步迭代器利用它与编译器期望的不同.

您可以通过向项目添加单独的源文件来修复此问题,其中包含此桥接代码.再次编译,一切都应该工作得很好.

更新

看起来Enumerable.Range()在异步迭代器中使用时会出现另一个错误.

问题中的GetNumbersAsync()方法仅在两次迭代后结束:

static async Task Main(string[] args)
{
    await foreach (var num in GetNumbersAsync())
    {
        Console.WriteLine(num);
    }
}

private static async IAsyncEnumerable<int> GetNumbersAsync()
{
    var nums = Enumerable.Range(0, 10);
    foreach (var num in nums)
    {
        await Task.Delay(100);
        yield return num;
    }
}
Run Code Online (Sandbox Code Playgroud)

这将仅打印:

0
1
Run Code Online (Sandbox Code Playgroud)

对于数组甚至另一个迭代器方法,这不会发生:

private static async IAsyncEnumerable<int> GetNumbersAsync()
{
    foreach (var num in counter(10))
    {
        await Task.Delay(100);
        yield return num;
    }
}

private static IEnumerable<int> counter(int count)
{
    for(int i=0;i<count;i++)
    {
        yield return i;
    }
}
Run Code Online (Sandbox Code Playgroud)

这将打印预期的:

0
1
2
3
4
5
6
7
8
9
Run Code Online (Sandbox Code Playgroud)

更新2

似乎这也是一个已知错误: Async-Streams:迭代在Core上提前停止