빈 IAsyncEnumerable 생성


25

다음과 같이 작성된 인터페이스가 있습니다.

public interface IItemRetriever
{
    public IAsyncEnumerable<string> GetItemsAsync();
}

다음과 같이 항목을 반환하지 않는 빈 구현을 작성하고 싶습니다.

public class EmptyItemRetriever : IItemRetriever
{
    public IAsyncEnumerable<string> GetItemsAsync()
    {
       // What do I put here if nothing is to be done?
    }
}

그것이 일반적인 IEnumerable이라면 return Enumerable.Empty<string>();, 나는 할 것이지만 찾지 못했습니다 AsyncEnumerable.Empty<string>().

해결 방법

나는 이것이 효과가 있지만 꽤 이상하다는 것을 알았다.

public async IAsyncEnumerable<string> GetItemsAsync()
{
    await Task.CompletedTask;
    yield break;
}

어떤 생각?

답변:


28

System.Linq.Async패키지 를 설치하면 을 사용할 수 있어야합니다 AsyncEnumable.Empty<string>(). 다음은 완전한 예입니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        IAsyncEnumerable<string> empty = AsyncEnumerable.Empty<string>();
        var count = await empty.CountAsync();
        Console.WriteLine(count); // Prints 0
    }
}

신속한 답변과 제안에 감사드립니다. 프레임 워크에 무언가가 있기를 바랐습니다.
cube45

@ cube45 : 저는 일반적 System.Linq.Async으로 "가상적으로 프레임 워크의 일부"로 간주 합니다. 약간의 그있어 단지 가에 올 때 netstandard2.1에 IAsyncEnumerable<T>.
Jon Skeet

@ cube45 나는 패키지를 사용하지 않도록 조심할 것입니다. 너무 많은 작업을 시작했을 때 알게 될 비동기 흐름이있는 많은 쿼크가 있습니다.
Filip Cordas

답변 주셔서 감사합니다. 나는 이전에 IAsyncEnumerable을 사용한 적이 없었으며 실험을 위해 "진짜로"무언가를하지 않았습니다. 당신 말이 맞을 것입니다. 패키지가 유용 할 수 있습니다.
cube45


11

어떤 이유로 든 Jon의 답변에 언급 된 패키지를 설치하지 않으려는 경우 다음 AsyncEnumerable.Empty<T>()과 같은 방법을 만들 수 있습니다 .

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
public static class AsyncEnumerable
{
    public static IAsyncEnumerator<T> Empty<T>() => EmptyAsyncEnumerator<T>.Instance;

    class EmptyAsyncEnumerator<T> : IAsyncEnumerator<T>
    {
        public static readonly EmptyAsyncEnumerator<T> Instance = 
            new EmptyAsyncEnumerator<T>();
        public T Current => default!;
        public ValueTask DisposeAsync() => default;
        public ValueTask<bool> MoveNextAsync() => new ValueTask<bool>(false);
    }
}

참고 : 대답은 System.Linq.Async패키지 사용을 권장하지 않습니다 . 이 답변은 AsyncEnumerable.Empty<T>()필요하고 패키지를 사용할 수 없거나 원하지 않는 경우 에 대한 간단한 구현을 제공 합니다. 패키지 에서 사용 된 구현은 여기 에서 찾을 수 있습니다 .


답변 주셔서 감사합니다. 실제로, 그것은 옵션이기도합니다. 다른 패키지를 설치하는 것보다 그 방법을 선호한다고 생각합니다. 이것을 승인 된 것으로 표시하겠습니다. Nitpick : "확장 메소드"는 정적 클래스의 정적 메소드 일뿐입니다.
cube45

1
@ cube45 : 그렇다면 비동기 시퀀스에 LINQ 기능을 사용할 계획이 없습니까? 일반적으로 동기식 LINQ로 수행하려는 작업을 수행하자마자 System.Linq.Async가 필요합니다.
Jon Skeet
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.