C# 异步填充字典

C# 异步填充字典,c#,.net,asp.net-core,.net-core,C#,.net,Asp.net Core,.net Core,我有一个简单的foreach循环(如下所示),它迭代一个集合,并根据当前迭代器值进行异步API调用以获取数据 foreach(组中的变量组) { var usersInGroup=wait this.tableauService.GetUsersInTableauGroup(group.Id); //请使用“usersInGroup”` } 我不希望每次迭代都进行API调用,而是希望为每个API调用创建一个异步任务,并同时执行它们,结果填充由group.Id键入的字典。这可能吗 在我看来,代码

我有一个简单的
foreach
循环(如下所示),它迭代一个集合,并根据当前迭代器值进行异步API调用以获取数据

foreach(组中的变量组)
{
var usersInGroup=wait this.tableauService.GetUsersInTableauGroup(group.Id);
//请使用“usersInGroup”`
}
我不希望每次迭代都进行API调用,而是希望为每个API调用创建一个异步任务,并同时执行它们,结果填充由
group.Id
键入的字典。这可能吗

在我看来,代码应该是这样的:

IList tasks=new List();
IDictionary dictionary=新字典();
foreach(组中的var组)
{
添加(this.tableauService.getUsersInTableAugGroup(group.Id));
//以某种方式定义每个任务的回调以创建字典
}
等待任务。何时(任务);

您希望为并行化
,而不是每个循环周期内的工作。使用
Parallel.ForEach

您想要并行化
,而不是每个循环周期内的工作。使用
Parallel.ForEach

尝试以下代码:


        public async Task<(string name, int id)> Aggregate(int id)
        {
            var result = await this.tableauService.GetUsersInTableauGroup(id);
            return (result, id);
        }

...
            var tasks = await Task.WhenAll(groups.Select(g => Aggregate(g.Id)));

            var dict = tasks.ToDictionary(k => k.id, k => k.name);


公共异步任务聚合(int-id)
{
var result=wait this.tableauService.getUsersInTableAugGroup(id);
返回(结果、id);
}
...
var tasks=wait Task.WhenAll(groups.Select(g=>Aggregate(g.Id));
var dict=tasks.ToDictionary(k=>k.id,k=>k.name);
它将异步运行所有API调用,一旦所有这些请求完成,我们就可以根据结果安全地创建一个字典,请尝试以下代码:


        public async Task<(string name, int id)> Aggregate(int id)
        {
            var result = await this.tableauService.GetUsersInTableauGroup(id);
            return (result, id);
        }

...
            var tasks = await Task.WhenAll(groups.Select(g => Aggregate(g.Id)));

            var dict = tasks.ToDictionary(k => k.id, k => k.name);


公共异步任务聚合(int-id)
{
var result=wait this.tableauService.getUsersInTableAugGroup(id);
返回(结果、id);
}
...
var tasks=wait Task.WhenAll(groups.Select(g=>Aggregate(g.Id));
var dict=tasks.ToDictionary(k=>k.id,k=>k.name);
它将异步运行所有API调用,一旦所有这些请求完成,我们就可以安全地从任务的结果创建一个字典。WhenAll()返回任务的所有值,因此您可以执行以下操作:

var tasks = groups
  .Select(async g => new 
  {
    g.Id, 
    Values = await this.tableauService.GetUsersInTableauGroup(g.Id)
  });
var results = await Task.WhenAll(tasks);
var dictionary = results
  .ToDictionary(r => r.Id, r => r.Values);
Task.WhenAll()返回任务的所有值,因此可以执行以下操作:

var tasks = groups
  .Select(async g => new 
  {
    g.Id, 
    Values = await this.tableauService.GetUsersInTableauGroup(g.Id)
  });
var results = await Task.WhenAll(tasks);
var dictionary = results
  .ToDictionary(r => r.Id, r => r.Values);

只有键操作不是线程安全的,读取键是线程安全的,他没有在代码中显示如何使用字典。一本普通的
字典
可能很好。OP特别指出他正在尝试填充字典,这意味着他将调用
Add
。。。。或者使用:
ConcurrentDictionary
只有键操作不是线程安全的,读取键是线程安全的,他没有在代码中显示他如何使用字典。一本普通的
字典
可能很好。OP特别指出他正在尝试填充字典,这意味着他将调用
Add
。。。。或者使用:
concurrentdirectionary
@SoheilAlizadeh:No,它生成一个
任务
——返回
Func
。(否则,
Task.whalll()
如何等待这些任务并得到它们的结果?@SoheilAlizadeh它不会返回空,它是一个
Func
@StriplingWarrior似乎是一个很好的解决方案,我没法四处走动,可能需要咖啡……谢谢。让我知道是否有任何部分我可以帮助更好地解释。这正是我想要的,谢谢@StriplingWarrior@SoheilAlizadeh:否,这将生成一个
任务
——返回
Func
。(否则,
Task.whalll()
如何等待这些任务并得到它们的结果?@SoheilAlizadeh它不会返回空,它是一个
Func
@StriplingWarrior似乎是一个很好的解决方案,我没法四处走动,可能需要咖啡……谢谢。如果有什么地方我可以更好地解释,请告诉我。这正是我想要的,谢谢@StriplingWarrior