【问题标题】:Should I use synchronous/asynchronous API calls when creating an API that calls 2 other APIs?在创建调用其他 2 个 API 的 API 时,我应该使用同步/异步 API 调用吗?
【发布时间】:2019-03-25 02:55:32
【问题描述】:

我正在创建一个 API,作为应用程序和其他 2 个 API 之间的桥梁。我想知道最好的方法是什么。我正在使用 HttpClient。该应用程序有近一千个用户,所以如果我使用同步调用,这是否意味着如果用户调用 API,那么其他用户必须等到第一个用户得到响应才能继续处理其他 API 请求?有没有更好的方法来做这样的 API?

这是我使用同步的代码示例:

[HttpGet]
[Route("api/apiname")]     
public String GetNumberofP([FromUri]GetNumberofPRequest getNPRequest){          

    var request = JsonConvert.SerializeObject(getNPRequest);
    string errorMessage = "";           

    try{              
         httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.gettoken());

         var response = httpClient.GetAsync("api/MobileApp/GetNumberP?"
                          + "strCardNumber=" + getNPRequest.strCardNumber
                         + "&strDateOfBirth=" + getNPRequest.strDateOfBirth).Result;
         return response;
    }            
    catch (Exception e){                
        throw utils.ReturnException("GetNumberofP", e, errorMessage);           
    }      
}

【问题讨论】:

  • 将同步调用转换为异步调用总是很容易,但反之则充满危险。你应该让你的 API 异步。
  • 另外catch (Exception e) 是一个糟糕的反模式。您应该只捕获您可以有意义处理的特定异常。
  • 这真的取决于。虽然编写代码需要遵循一些规则,以便于代码的维护。但设计模式不是圣经。

标签: c# asp.net-web-api httpclient


【解决方案1】:

如果我使用同步调用,这是否意味着如果用户调用 API,那么其他用户必须等到第一个用户获得响应才能继续执行其他 API 请求

没有。当请求进入管道时,框架会产生一个新线程。因此,如果同时有 1000 个请求进入,第 1000 个用户将不必等待其他 999 个请求完成。

无论如何,您最好使用异步代码。对于像网络请求这样的任何 I/O,通常最好让后台线程进行等待以提高性能。旁注,您永远不想调用.Result,因为这会迫使异步代码变为阻塞并有效地变为同步。

【讨论】:

    【解决方案2】:

    将同步调用转换为异步调用总是很容易,但反之则充满危险。你应该让你的 API 异步。

    [HttpGet]
    [Route("api/apiname")]
    public Task<string> GetNumberofP([FromUri]GetNumberofPRequest getNPRequest)
    {
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.gettoken());
        return httpClient.GetAsync($"api/MobileApp/GetNumberP?strCardNumber={getNPRequest.strCardNumber}&strDateOfBirth={getNPRequest.strDateOfBirth}");
    }
    

    您还应该考虑为每个呼叫创建一个新的httpClient。

    【讨论】:

    • 你的意思是把我的 httpclient 包装在这样的 using 语句中: using(var client = new HttpClient()) { //do something with http client }
    • @KateLastimosa - 是的,正是如此。
    • 我应该使用 using 语句是否有特定的行为?这就是我最初的做法。但有些文章说不要那样做。链接在这里。 aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong
    • @KateLastimosa - 我以前没见过这一切。听起来一切都太复杂了。也许改用WebClient。
    【解决方案3】:

    您似乎缺少 async 和 await 关键字。

    public async String GetNumberofP([FromUri]GetNumberofPRequest getNPRequest){
            
    (...)
    
             var response = await httpClient.GetAsync();
    

    【讨论】:

      猜你喜欢
      • 2014-08-13
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      • 1970-01-01
      • 2017-12-24
      • 1970-01-01
      • 1970-01-01
      • 2018-01-30
      相关资源
      最近更新 更多