빈 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.