Async方法被其他线程重复调用问题求助(仅云环境出现)
问题:Sync方法被重复执行排查
背景
我正在调用如下端点,从我方使用的专有API拉取数据。在Sync2方法中通过并行调用获取订单详情,当对方API返回429状态码时,我方会延迟一段时间后重试(目前为基础重试,后续将改为指数退避),同时通过SignalR发送该流程的实时更新。
问题现象
当Sync2方法仍在执行时,Provider.Sync方法被另一个线程再次调用。Sync2需处理约400个订单,需发起400次API调用,我按每组5个进行并发调用。查看App Insights日志发现,OnExecutingAsync过滤器也被再次触发。无法定位问题根源,不知为何会再次执行同一方法。
补充信息
- 并未从UI端再次调用该端点
- 该问题仅在云环境实例中出现,本地环境无此问题
附带代码
[HttpGet("orders/sync")] public async Task<IActionResult> Sync() { var result = await Provider.Sync(); return Ok(result); } public static class Provider { public static async Task<IEnumerable<string>> Sync() { var result = await Sync1(); await _hubcontext.Clients.Group("user").SendAsync("liveUpdates", new SyncProgress("Sync1 complete.", 50)); if(result){ var orderDetails = await Sync2(); // 需处理约400个订单,发起400次API调用,按每组5个并发执行 await _hubcontext.Clients.Group("user").SendAsync("liveUpdates", new SyncProgress("Sync2 complete.", 100)); return orderDetails; } return Enumerable.Empty<string>(); } private static async Task<IEnumerable<string>> Sync2() { List<string> orders = new List<string> {"12345", "23456", "12345", "23456", "12345", "23456"}; var tasks = orders.Select(order => ApiClient.GetAsync($"/v1/orders/{order}", "xddsw")); // GetAsync返回Task,等待目标端点的结果 var responses = await Task.WhenAll(tasks); // 原代码遗漏返回逻辑,此处为推测补充 return responses.Select(r => /* 处理响应并返回字符串 */); } } public async static Task<T?> GetAsync<T>(string apiUrl, string accessToken = "", RestRequest request = default, int retryOption = 0) { request ??= new RestRequest(apiUrl); request.AddHeader("Accept", "application/json"); if (!string.IsNullOrEmpty(accessToken)) { request.AddHeader("Authorization", $"Bearer {accessToken}"); } var response = await ApiClient.ExecuteGetAsync(request); if (!response.IsSuccessful) { var statusCode = (int)response.StatusCode; if (statusCode == StatusCodes.Status429TooManyRequests) { if (retryOption > 3) throw new Exception("请求过多,请稍后重试", statusCode); await Task.Delay(60000); return await GetAsync<T>(apiUrl, accessToken, retryOption: ++retryOption); } else { throw new Exception(response.Content, statusCode); } } return response.Content.Length > 2 ? JsonConvert.DeserializeObject<T>(response.Content) : default; }
排查方向
- 云环境网关/负载均衡器超时重试:检查云平台(如Azure App Service、AWS ALB等)的请求超时配置,如果Sync方法因429重试导致执行时间超过网关阈值,网关可能自动发起重试请求。查看云平台请求日志,确认重复请求的发起方。
- 请求来源追踪:在App Insights中通过请求ID关联两次Sync调用的日志,查看请求头(如
X-Forwarded-For、X-Original-URI)和来源IP,确认请求是外部发起还是内部组件触发。 - SignalR连接重连逻辑:检查前端SignalR连接的重连回调,是否存在重连后自动触发Sync的逻辑,即使手动未调用。
- 应用进程/池重启:查看云环境中应用的重启日志,确认是否有意外重启导致初始化逻辑或定时任务自动触发Sync方法。
- 静态类线程安全:
Provider是静态类,确认_hubcontext的初始化和使用是否线程安全,是否存在异常导致的间接重试触发。
内容的提问来源于stack exchange,提问作者yaswanth nidumukkala
相关产品推荐
相关产品推荐

