You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Microsoft Graph的Planner任务数量检索性能优化及重试策略需求

优化Microsoft Graph Planner任务数量核对性能与实现重试机制

我之前在做类似的Planner对接项目时也碰到过批量Plan任务计数慢的问题,结合你的Angular+ASP.NET架构,给你分享几个实用的优化方案和重试机制实现思路:

一、性能优化:从39秒到秒级响应的关键调整

1. 用Graph批量请求($batch)减少HTTP开销

逐个请求205个Plan的任务数量,光是HTTP握手和连接建立就占了大部分时间。Microsoft Graph支持批量请求,可以把最多20个独立请求打包成一个POST请求发送,大幅减少网络往返次数。

举个ASP.NET里的实现示例:

var batchRequestContent = new BatchRequestContent();
var planIds = // 你的205个Plan ID集合
int batchSize = 20;
// .NET 6+可用Chunk,低版本可自行实现分块逻辑
var batches = planIds.Chunk(batchSize);

foreach (var batch in batches)
{
    foreach (var planId in batch)
    {
        var countRequest = _graphServiceClient.Planner.Plans[planId].Tasks.Count.Request();
        var requestId = Guid.NewGuid().ToString();
        batchRequestContent.AddBatchRequestStep(countRequest, requestId);
    }

    var batchResponse = await _graphServiceClient.Batch.Request().PostAsync(batchRequestContent);
    // 解析每个请求的计数结果
    foreach (var requestId in batchRequestContent.BatchRequestSteps.Keys)
    {
        var countResponse = await batchResponse.GetResponseAsync<int>(requestId);
        // 处理countResponse.Body的数值,比如存入数据库或返回前端
    }
}

这样205个Plan只需要11个批量请求,能把时间压缩到几秒内。

2. 直接请求任务计数,不要拉取全量任务

别傻乎乎地把所有任务拉回来再Count()!Graph支持直接返回任务数量,用$count参数:

var taskCount = await _graphServiceClient.Planner.Plans[planId].Tasks
    .Count
    .Request()
    .GetAsync();

如果需要过滤特定状态的任务(比如只算未完成任务),可以加$filter:

var activeTaskCount = await _graphServiceClient.Planner.Plans[planId].Tasks
    .Count
    .Request()
    .Filter("percentComplete ne 100")
    .GetAsync();

这个方法能让Graph服务器帮你做计数,不用传输大量任务数据,带宽和处理时间都省了。

3. 加入缓存策略

如果你的任务数量不需要实时到秒级,可以给计数结果加缓存。ASP.NET里用IMemoryCache或者分布式缓存(比如Redis):

public async Task<int> GetPlanTaskCountAsync(string planId)
{
    var cacheKey = $"Planner_TaskCount_{planId}";
    if (_memoryCache.TryGetValue(cacheKey, out int count))
    {
        return count;
    }

    count = await _graphServiceClient.Planner.Plans[planId].Tasks.Count.Request().GetAsync();
    // 设置5分钟过期,可根据业务调整
    _memoryCache.Set(cacheKey, count, TimeSpan.FromMinutes(5)); 
    return count;
}

重复请求同一个Plan时直接读缓存,完全跳过Graph调用。

4. 并行请求+限流控制

如果不想用批量请求,也可以用Task.WhenAll并行发起请求,但一定要控制并发数,避免触发Graph的速率限制(429错误):

var semaphore = new SemaphoreSlim(10); // 限制同时10个请求
var tasks = planIds.Select(async planId =>
{
    await semaphore.WaitAsync();
    try
    {
        return await _graphServiceClient.Planner.Plans[planId].Tasks.Count.Request().GetAsync();
    }
    finally
    {
        semaphore.Release();
    }
});

var counts = await Task.WhenAll(tasks);

这种方式比串行快,但还是不如批量请求高效。

二、实现可靠的重试机制

对接Graph一定要处理429(速率限制)、5xx(服务器错误)这类临时错误,推荐用Polly库来实现重试策略,比手动写重试逻辑灵活得多。

1. 安装Polly并配置重试策略

首先安装Polly包:

# NuGet包管理器安装
Install-Package Polly
# 或.NET CLI安装
dotnet add package Polly

然后在Program.cs里注册重试策略(ASP.NET 5写法):

var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .OrResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.TooManyRequests || (int)r.StatusCode >= 500)
    .WaitAndRetryAsync(3, retryAttempt => 
        TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)) // 指数退避:2s→4s→8s
    );

2. 在Graph调用中使用重试策略

把Graph请求包在Polly的策略里:

var taskCount = await retryPolicy.ExecuteAsync(async () =>
{
    return await _graphServiceClient.Planner.Plans[planId].Tasks.Count.Request().GetAsync();
});

如果遇到429或5xx错误,会自动重试3次,每次间隔翻倍,避免频繁请求加重服务器负担。

3. 处理Graph的Retry-After头

当Graph返回429时,会附带Retry-After头告诉你多久后可以重试。Polly可以配置读取这个头来动态调整等待时间:

var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .OrResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.TooManyRequests)
    .WaitAndRetryAsync(3, (retryAttempt, response, context) =>
    {
        if (response.Result.StatusCode == HttpStatusCode.TooManyRequests &&
            response.Result.Headers.TryGetValues("Retry-After", out var values) &&
            int.TryParse(values.First(), out var retryAfter))
        {
            return TimeSpan.FromSeconds(retryAfter);
        }
        return TimeSpan.FromSeconds(Math.Pow(2, retryAttempt));
    });

这样更贴合Graph的限流规则,重试成功率更高。

最后提醒

别忘了注意Microsoft Graph Planner的速率限制,避免短时间内请求过多被限流,影响整体性能。

内容的提问来源于stack exchange,提问作者Leonardo Heis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:28:44