代码之家  ›  专栏  ›  技术社区  ›  SkyeBoniwell

在每个返回的响应之间等待一秒钟

  •  0
  • SkyeBoniwell  · 技术社区  · 3 年前

    该API限制为每秒3个连接。

    它工作得很好,但我发现如果某个工厂有很多员工,我会达到API连接限制并得到一个错误。

    (429) API calls exceeded...maximum 3 per Second

    所以我决定用 await Task.Delay(1000) 要设置1秒延迟,每次使用此方法时。

    现在,它似乎已经减少了我得到的错误数量,但我仍然得到一些极限错误。

    public async Task<YourSessionResponder> GetAll(Guid factoryId)
        {
            UserSession.AuthData sessionManager = new UserSession.AuthData
            {
                UserName = "xxxx",
                Password = "xxxx"
            };
    
    
            ISessionHandler sessionMgr = new APIclient();
    
            YourSessionResponder response;
    
            response = await sessionMgr.GetDataAsync(sessionManager, new ListerRequest
            {
                FactoryId = factoryId;
    
            await Task.Delay(1000);
            return response;
        }
    

    我这样称呼它:

    var yourEmployees = GetAll(factoryId);
    
    2 回复  |  直到 3 年前
        1
  •  1
  •   David    3 年前

    根据对该问题的评论:

    我这样称呼它: var yourEmployees = GetAll(factoryId);

    var yourEmployees = await GetAll(factoryId);
    

    当然,假设这是在某种循环或重复操作中发生的。否则,所有这些不同的网络任务将从何而来?无论高级逻辑调用多个网络操作,该逻辑都需要等待一个操作,然后再进行下一个操作。

        2
  •  2
  •   Stephen Cleary    3 年前

    我有一个连接到外部API的web应用程序。

    单一的 对API的传入请求。你需要做的是限制 应用程序范围内的传出请求。

    可能的 SemaphoreSlim :

    private static readonly SemaphoreSlim Mutex = new(1);
    public async Task<YourSessionResponder> GetAll(Guid factoryId)
    {
      ...
      YourSessionResponder response;
    
      await Mutex.WaitAsync();
      try
      {
        response = await sessionMgr.GetDataAsync(...);
        await Task.Delay(1000);
      }
      finally
      {
        Mutex.Release();
      }
    
      return response;
    }
    

    但我会采取不同的方法。。。

    一般来说,我建议只对429个错误重试,使用去相关的抖动指数退避(参见 Polly 以便于实现)。这样,当您在一段时间内处于“预算不足”状态时,您的请求会立即通过,只有当您达到API限制时,请求才会减慢速度。