我想在一堆ToDictionary
上使用Task<MyObject>
(请参见下文)。如果我使用TheTask.Result
,但不等待
这有效:
Dictionary<CarId, Task<Model>> allModelTasks = carIds.ToDictionary(cId =>cId, cId=> GetModelForCar(cId));
await Task.WhenAll(allModelTasks.Values);
Dictionary<CarId, Model> allModels = allModelTasks.ToDictionary(mt => mt.Key, mt => mt.Value.Result);
但是如果我将最后一行替换为
Dictionary<CarId, Model> allModels = allModelTasks.ToDictionary(mt => mt.Key, async mt => await mt.Value);
我收到一条错误消息,内容为“无法从Dict<CarId, Task<Model>>
转换为Dict<CarId, Model>
”。
如我所见,这些行应该等效。
(建议from here似乎是使用await代替.Result
,即使在 EDIT Task.WhenAll
之后)
答案 0 :(得分:8)
您似乎忽略了能够在最后一行中写await
,还必须添加另一个async
。这意味着await
不在您当前的方法中-它位于新的async
lambda中,当然,被async
返回的是Task
。
您不能在此处的lambda中使用await
,并且期望没有任务要展开。您的第一个代码很好,并且不会遇到访问.Result
可能引起的任何潜在问题,因为众所周知Task
已经完成。
您可以创建或复制某种形式的ToDictionaryAsync
扩展方法到您的类中,例如:
public static class TaskResultExtensions
{
public static async Task<Dictionary<TKey, TValue>> ToDictionaryAsync<TKey, TValue>(this IEnumerable<KeyValuePair<TKey, Task<TValue>>> source)
{
var dict = new Dictionary<TKey, TValue>();
foreach (var kvp in source)
{
dict.Add(kvp.Key, await kvp.Value);
}
return dict;
}
}
然后允许您使用最后一行
Dictionary<CarId, Model> allModels = await allModelTasks.ToDictionaryAsync();
相反。