异步方法被另一个线程第二次调用

问题描述 投票:0回答:1

我正在调用如下所示的端点,该端点从我们正在使用的专有 API 中提取数据。

我正在

Sync2
方法中进行并行调用以获取订单详细信息。由于他们的 API 返回 429,我们延迟了一段时间,然后再次进行调用。 (我知道这是非常基本的,我们可能必须采用指数延迟。但我们正在实现这一点。)。我正在使用 SignalR 发送此过程的实时更新。

问题:

MasterSync
方法正在被另一个线程再次调用,而
Sync2
方法仍在执行。
Sync2
必须带来大约 400 个订单的数据。因此,我们必须进行 400 个 API 调用。我以 5 个为一组进行并发调用。我们还有一个
OnExecutingAsync
过滤器,甚至当我检查 App Insights 日志时,该方法也会被调用。 我无法弄清楚我在这里缺少什么以及为什么控件再次返回并执行相同的方法。

我不会再次从 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(); // This has to bring data for around 400 orders. So, we have to make 400 API calls. I'm making concurrent calls in chunks of 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 returns a Task and I'm awaiting on the result from the endpoint that I'm calling.
        var responses = await Task.WhenAll(tasks);
    }

}

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("TooMany Requests. Please try aftersome time", 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;
}
c# async-await concurrency task-parallel-library webapi
1个回答
0
投票

处理请求需要多长时间?我不知道是什么在调用该 GET 方法,但它有可能有重试策略吗?

默认的http超时时间大概是100秒左右。您的内部重试有 60 秒的延迟。

想象一下有人调用你的 http 方法。 GetAsync 收到 429,等待 60 秒重试...原始调用者现在等待多长时间?再次重试,也许......调用者将在您的函数认为它完成之前超时。

对服务进行 http 调用,然后重试另一个服务等...这可能会导致根客户端长时间超时。

希望有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.