C#等待X和.Result在ToDictionary()中不相等?
我想在一堆C#等待X和.Result在ToDictionary()中不相等?,c#,async-await,C#,Async Await,我想在一堆任务(见下文)上使用ToDictionary。如果我使用task.Result(任务结果),这可以正常工作,但不等待 这项工作: Dictionary<CarId, Task<Model>> allModelTasks = carIds.ToDictionary(cId =>cId, cId=> GetModelForCar(cId)); await Task.WhenAll(all
任务
(见下文)上使用ToDictionary
。如果我使用task.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 allmodelstasks=carIds.ToDictionary(cId=>cId,cId=>GetModelForCar(cId));
wait Task.WhenAll(allmodelstasks.Values);
字典allModels=allmodelstasks.ToDictionary(mt=>mt.Key,mt=>mt.Value.Result);
但如果我将最后一行替换为
Dictionary<CarId, Model> allModels = allModelTasks.ToDictionary(mt => mt.Key, async mt => await mt.Value);
Dictionary allModels=allmodelstasks.ToDictionary(mt=>mt.Key,async mt=>await mt.Value);
我收到一条错误消息,上面写着“无法从Dict
转换为Dict
”。
在我看来,行应该是等价的
(建议使用wait而不是
.Result
,即使在编辑任务之后也是如此。当所有的都完成时)您似乎忽略了这一点,为了能够在最后一行中编写wait
,您还必须添加另一个异步。这意味着await
不在当前方法中-它在一个新的async
lambda中,当然,异步async
返回一个任务
您不能在lambda中使用等待
,而期望没有任务要展开。您的第一个代码很好,并且不会遇到访问.Result
可能导致的任何潜在问题,因为任务都已完成
您可以在类中创建或复制某种形式的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;
}
}
公共静态类TaskResultTextensions
{
公共静态异步任务ToDictionaryAsync(此IEnumerable源)
{
var dict=新字典();
foreach(源中的var kvp)
{
dict.Add(kvp.Key,等待kvp.Value);
}
返回命令;
}
}
这样你的最后一行就可以
Dictionary<CarId, Model> allModels = await allModelTasks.ToDictionaryAsync();
Dictionary allModels=wait allmodelstasks.ToDictionaryAsync();
相反。请注意编辑-我的编辑使用正确的语法使泛型可见。例如,在第一段中,你的任务消除了这一点,使它们不可见。GetModelForCar
看起来如何?@PavelAnikhouski鉴于第一个代码是有效的,Task GetModelForCar(CarId)
。看看这个问题:它包含了一个ToDictionaryAsync
方法的实现。这些实现按顺序等待每个值,因此它不是您想要的。这说明了为什么没有这样的内置方法:它可以以多种方式实现,具有不同的行为。“即使在Task.WaitAll之后”-建议也是:避免WaitAll
:)好的,是的。我明白了。结果是ok bec of WhenAll(),但我希望它与Wait,bec一起工作。(1) 在我当前的项目中,我的代码可能是复制粘贴的,不希望为阻止reaseon而加密.Result。(2) 我可能无法100%确定Stephen Cleary在anwer中的意思(“我建议使用Wait,因为它显然是正确的,而结果可能会在其他场景中导致问题。”)。如果这些场景没有任何等待/等待()。。。但主要是出于好奇。我想说的是:我应该把等待放在哪里?你能帮我纠正最后一行吗?@Cowborg-如果在最后一行中有一个简单的地方放置wait
,我会建议的。如果您确实想等待
,那么您可以自己创建一个新词典,然后迭代第一个词典的内容,依次等待每个值,然后再添加到新词典中。但我发现这是一个“噪音更大”的实现。