Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

async Task<IEnumerable<T>> throws "is not an iterator interface type" error

The following code is throwing is not an iterator interface type only when I use async await and wrap the IEnumerable with Task. If I remove async await, it will work with IEnumerable<List<T>>.

private async Task<IEnumerable<List<T>>> GetTableDataAsync<T>(CloudTable cloudTable, TableQuery<T> tableQuery)
        where T : ITableEntity, new()
    {
        TableContinuationToken contineousToken = null;
        do
        {
            var currentSegment = await GetAzureTableDateAsync(cloudTable, tableQuery, contineousToken);
            contineousToken = currentSegment.ContinuationToken;
            yield return currentSegment.Results;

        } while (contineousToken != null);

    }

Though I can consider Rx, I am not sure what is causing this issue.

like image 792
Saravanan Avatar asked Feb 26 '14 08:02

Saravanan


2 Answers

Only methods declaring that they return IEnumerable<T>, IEnumerable, IEnumerator or IEnumerator<T> can be implemented with iterator blocks. That rules out all async methods.

Fundamentally it's not clear how they'd work anyway, given that IEnumerable<T> is pull-based, whereas asynchronous methods are more reactive. Also, the point of an iterator block is that callers can see intermediate results - whereas the task returned from an async method will not complete until the async method itself has completed.

You'll need to go for an alternative approach - whether that's Rx or something else. You might want to think first not about what the implementation will look like, but what the caller will do. Perhaps you actually want an IEnumerable<Task<List<T>>?

like image 58
Jon Skeet Avatar answered Oct 29 '22 16:10

Jon Skeet


old question, and the accepted answer is correct, however now with c#8, IAsyncEnumerable was introduced. so instead of IEnumerable you should use the IasyncEnumerable. see the docs at https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#asynchronous-streams

Example:

public static async System.Collections.Generic.IAsyncEnumerable<int> GenerateSequence()
{
    for (int i = 0; i < 20; i++)
    {
        await Task.Delay(100);
        yield return i;
    }
}

Calling code:

await foreach (var number in GenerateSequence())
{
    Console.WriteLine(number);
}
like image 42
Lys Avatar answered Oct 29 '22 18:10

Lys