Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#等待X和.Result在ToDictionary()中不相等?_C#_Async Await - Fatal编程技术网

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
,我会建议的。如果您确实想
等待
,那么您可以自己创建一个新词典,然后迭代第一个词典的内容,依次等待每个值,然后再添加到新词典中。但我发现这是一个“噪音更大”的实现。