c# - 存储在字典对象中的异步 Http GET 任务
问题描述
我正在努力减少延迟并提高我的应用程序的响应能力。在我的 API 控制器(Asp .NET Core)中
我正在使用 anHttpClient
对服务器执行多个请求,获取事件和任务信息。
我为用户关联的每个组执行两个请求(我使用 Microsoft Graph API 获取此信息);一种用于事件,一种用于任务。
然后我等待他们的结果,如果他们不返回 null,则将它们附加到我的字典对象中,以组的名称命名。
返回对象:
Group 1
-- Incidents ArrayList
-- Tasks ArrayList
Group 2
-- Incidents ArrayList
-- Tasks ArrayList
...
我的代码如下:
Dictionary<string, ArrayList> final;
Microsoft.Graph.Group group_details;
string group_name;
using (var client = ClientFactory.GetClientAsync(_apiCredentials))
{
//for each group send request to get past 30 day's incidents and tasks
foreach (var group in groups.CurrentPage)
{
//request to Graph API to get name of group for query
try
{
group_details = await _graphServiceClient.Groups[group.Id].Request()
.GetAsync();
group_name = group_details.DisplayName.Replace("#", "").Trim();
//creates async tasks for fetching Incidents and Tasks
var getIncidentsTask = GetIncidents(client, startDate, group_name);
var getTasksTask = GetTasks(client, startDate, group_name);
//awaits values
var Incidents = await getIncidentsTask;
var Tasks = await getTasksTask;
//if both Incidents and Tasks exist for current group
if (Incidents != null && Tasks != null)
{
final.Add(group_name, new ArrayList());
final[group_name].Add(Incidents);
final[group_name].Add(Tasks);
}
}
catch(Exception e)
{
_logger.LogError(e.Message);
}
}
}
我知道有一种更高级的方法可以等待这些任务。我试图使用Task.WhenAll()
,但是这只适用于 ,IEnumerable
所以我必须在每个组中挖掘一个层并循环遍历每个组,同时使用此语句在完成每组事件/任务时生成一个任务。
我的目标是让所有任务在后台运行完成,同时尽可能少地阻塞线程,然后如果每组结果不为空,则将它们附加到我的返回对象中。
如果有人对此有任何建议,我将不胜感激。
解决方案
这是“一个”解决方案。它允许您并行等待所有任务,同时保持每个组捆绑的结果。理论上,如果您愿意,如果您选择使用并发集合,则可以将向字典/数组列表添加值的逻辑移动到选择本身。
对不起,如果我在这里搞砸了。我尽量不要过度假设任何事情。Intellisense 也不起作用,因为您没有包含几个变量。
using (var client = ClientFactory.GetClientAsync(_apiCredentials))
{
var results = await Task.WhenAll(
groups.CurrentPage
.Select(async group => {
try
{
var details = await _graphServiceClient.Groups[group.Id].Request().GetAsync();
var name = details.DisplayName.Replace("#", "").Trim();
// fetching Incidents and Tasks
var incidentsTask = GetIncidents(client, startDate, name);
var tasksTask = GetTasks(client, startDate, name);
await Task.WhenAll(incidentsTask, tasksTask);
return new { name, incidents = incidentsTask.Result, tasks = tasksTask.Result };
}
catch (Exception e)
{
_logger.LogError(e.Message);
return null;
}
}));
foreach (var result in results.Where(x => x != null))
{
//if both Incidents and Tasks exist for current group
if (result.incidents != null && result.tasks != null)
{
final.Add(result.name, new ArrayList {
result.incidents,
result.tasks
});
}
}
}
推荐阅读
- python - pandas:在 pandas 中复制一个 excel 公式
- webrtc - 使用 TURN REST API 标志 (use-auth-secret) 的 WebRTC/ Coturn 身份验证,基于身份验证机密
- python - 从 Python 中的 SQL 类型地理列绘制多边形
- python - Selenium Python 点击只有一半的时间
- java - 无法导入 javax.persistence.MapsId
- python - 在Django的textarea中自动保存用户输入
- matlab - 将初始状态馈送到 MATLAB 中的 FMU 模块 (FMIKit)
- javascript - 将总和添加到对象中的每个元素并返回 Javascript 中的前 N 个键/值对
- flutter - 如何在 Flutter 中垂直和水平对齐 Container 内的文本?
- angular - Angular 项目需要很长时间才能重新加载更改