在尝试在async
中使用IEnumerable.SelectMany
lambda时,我得到了以下错误
var result = myEnumerable.SelectMany(async (c) => await Functions.GetDataAsync(c.Id));
不能从用法中推断方法“IEnumerable System.Linq.Enumerable.SelectMany(this IEnumerable,Func>)”的类型参数。尝试显式指定类型参数。
其中GetDataAsync
被定义为:
public interface IFunctions {
Task<IEnumerable<DataItem>> GetDataAsync(string itemId);
}
public class Functions : IFunctions {
public async Task<IEnumerable<DataItem>> GetDataAsync(string itemId) {
// return await httpCall();
}
}
我猜是因为我的GetDataAsync
方法实际上返回一个Task<IEnumerable<T>>
。但是为什么Select
要工作,当然它应该抛出同样的错误?
var result = myEnumerable.Select(async (c) => await Functions.GetDataAsync(c.Id));
有办法绕过这件事吗?
发布于 2015-11-03 09:48:47
异步lambda表达式不能转换为简单的Func<TSource, TResult>
。
因此,选择多个不能使用。您可以在同步上下文中运行:
myEnumerable.Select(c => Functions.GetDataAsync(c.Id)).SelectMany(task => task.Result);
或
List<DataItem> result = new List<DataItem>();
foreach (var ele in myEnumerable)
{
result.AddRange(await Functions.GetDataAsyncDo(ele.Id));
}
你既不能使用yield return
,也不能使用它--它是设计出来的。f.e.:
public async Task<IEnuemrable<DataItem>> Do()
{
...
foreach (var ele in await Functions.GetDataAsyncDo(ele.Id))
{
yield return ele; // compile time error, async method
// cannot be used with yield return
}
}
发布于 2016-03-08 18:17:10
这是一个扩展:
public static async Task<IEnumerable<T1>> SelectManyAsync<T, T1>(this IEnumerable<T> enumeration, Func<T, Task<IEnumerable<T1>>> func)
{
return (await Task.WhenAll(enumeration.Select(func))).SelectMany(s => s);
}
它允许您运行:
var result = await myEnumerable.SelectManyAsync(c => Functions.GetDataAsync(c.Id));
说明:您有一个任务列表,每个任务都返回Task<IEnumerable<T>>
。因此,您需要解雇他们,然后等待所有,然后通过SelectMany压扁结果。
发布于 2017-10-19 07:45:14
Select
之所以工作,是因为它将返回一个IEnumerable<Task<T>>
,然后可以与Task.WhenAll
一起等待。
因此,解决这个问题的一个简单方法是:
IEnumerable<Task<IEnumerable<T>>> tasks = source.Select(GetNestedEnumerableTask);
IEnumerable<T>[] nestedResults = await Task.WhenAll(tasks);
IEnumerable<T> results = nestedResults.SelectMany(nr => nr);
https://stackoverflow.com/questions/33495617
复制相似问题