问题 async Task > throws“不是迭代器接口类型”错误


以下代码正在抛出 不是迭代器接口类型 只有我用的时候 async  await 并包装 IEnumerable 与任务。如果我删除 async  await,我可以一起去 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);

    }

虽然我可以考虑Rx,但我不确定是什么导致了这个问题。


12862
2018-02-26 08:54


起源



答案:


只有声明他们返回的方法 IEnumerable<T>IEnumerableIEnumerator 要么 IEnumerator<T> 可以使用迭代器块实现。这排除了所有异步方法。

从根本上说,不管怎么说,他们的工作方式还不清楚 IEnumerable<T> 是基于拉的,而异步方法更具反应性。此外,迭代器块的要点是调用者可以看到中间结果 - 而异步方法返回的任务在异步方法本身完成之前不会完成。

你需要采取另一种方法 - 无论是Rx还是其他方法。你可能想要先考虑的不是什么 履行 看起来会像,但是什么 呼叫者 会做。也许你真的想要一个 IEnumerable<Task<List<T>>


15
2018-02-26 08:57



也许“IEnumerable <Task <List <T >>”会做。要求是读取所有azure表的值并提出一些指标(计数,总和),表的数量超过4k,给定过滤条件的记录将以百万计。我不想浪费线程,等待数据从azure返回 - Saravanan
@Saravanan:所以你需要考虑你的客户端代码会是什么样子。完全有可能迭代器块在这里不会真正帮助你 - 因为它们是一个阻塞拉模型。 - Jon Skeet
Rx走在前面。最近发布了一个NuGet包,它为表存储提供了一个反应接口 WindowsAzure.Storage sdk - Reactive.AzureStorage.Table - Saravanan


答案:


只有声明他们返回的方法 IEnumerable<T>IEnumerableIEnumerator 要么 IEnumerator<T> 可以使用迭代器块实现。这排除了所有异步方法。

从根本上说,不管怎么说,他们的工作方式还不清楚 IEnumerable<T> 是基于拉的,而异步方法更具反应性。此外,迭代器块的要点是调用者可以看到中间结果 - 而异步方法返回的任务在异步方法本身完成之前不会完成。

你需要采取另一种方法 - 无论是Rx还是其他方法。你可能想要先考虑的不是什么 履行 看起来会像,但是什么 呼叫者 会做。也许你真的想要一个 IEnumerable<Task<List<T>>


15
2018-02-26 08:57



也许“IEnumerable <Task <List <T >>”会做。要求是读取所有azure表的值并提出一些指标(计数,总和),表的数量超过4k,给定过滤条件的记录将以百万计。我不想浪费线程,等待数据从azure返回 - Saravanan
@Saravanan:所以你需要考虑你的客户端代码会是什么样子。完全有可能迭代器块在这里不会真正帮助你 - 因为它们是一个阻塞拉模型。 - Jon Skeet
Rx走在前面。最近发布了一个NuGet包,它为表存储提供了一个反应接口 WindowsAzure.Storage sdk - Reactive.AzureStorage.Table - Saravanan