c# - 如何为多个 http 请求重用 HttpClient 参考

我有一个代码,我在其中创建 HttpClient 的实例,它位于 foreach 循环内。这意味着每次迭代发生时它都会创建一个新实例。这是我的代码:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Net.Http.Headers;
using System.Net.Http;
using System.Text;
using System.Net.Mime;
using System.Net.Http.Json;

public class Program
   {
        static async Task Main(string[] args)
        {
            //JSON String
            string json = @"{
            'Values': [
                {
                    'MsgSource': null,
                    'TagName': 'Data.New_MSG',
                    'RawValue': '[\r\n  {\r\n    \'ID\': 145,\r\n    \'StationNo\': 6,\r\n    
                                 \'RunTime\': 1800,\r\n    \'ControllerID\': 4,\r\n    
                                 \'ControllerAddress\': 2,\r\n    \'ProgramNo\': 2,\r\n    
                                 \'ModeID\': \'AutoProgram\',\r\n    \'EventDate\': \'2022-04- 
                                 27T23:30:02\',\r\n    \'Description\': \'Irrigation 
                                 Completed\',\r\n    \'MessageCode\': 5\r\n,\r\n    
                                 \'ControllerName\': \'P25-SC-0233\'  },\r\n  {\r\n    \'ID\': 
                                 144,\r\n    \'StationNo\': 18,\r\n    \'RunTime\': 1800,\r\n    
                                 \'ControllerID\': 4,\r\n    \'ControllerAddress\': 2,\r\n    
                                 \'ProgramNo\': 5,\r\n    \'ModeID\': \'AutoProgram\',\r\n    
                                 \'EventDate\': \'2022-04-27T22:00:00\',\r\n    \'Description\': 
                                 \'Irrigation Completed\',\r\n    \'MessageCode\': 5\r\n,\r\n    
                                 \'ControllerName\': \'P25-SC-0226\'  }\r\n]',
                    'Status': 'Normal',
                    'ComStatus': null,
                    'TimeStamp': '2022-04-28 13:17:39.851'
                }
                ]
            }";

            //Deserializing JSON String
            Root root = JsonConvert.DeserializeObject<Root>(json);
            //Extracting the value of only RawValue key from the String
            string rawValue = root.Values[0].RawValue;

            //Creating List of ControllerName key            
            List<Station> stations = JsonConvert.DeserializeObject<List<Station>>(rawValue);
            
            JArray array = JArray.Parse(rawValue);
            
            int i = 0;    //Initializing Index to add ControllerName to the URL in Get http 
                          //request below
            foreach(var item in array) //Iterating through array
            {
                
                  var inc_val = i++;
                
                  using (var client = new HttpClient()) //Here I've Instantiated HttpClient
                  {
                    
                    client.DefaultRequestHeaders.Authorization = new 
                    AuthenticationHeaderValue("Basic","auth_value"); //Basic Auth

                    //Mandatory key for Message body in Post request
                    string isoTime = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
                    
                    //Concatenating ControllerName in URL and making get request
                    HttpResponseMessage get_response = await 
                    client.GetAsync("https://myurl.com/"+stations[inc_val]);

                    var get_responseString = await get_response.Content.ReadAsStringAsync();

                    JObject obj = JObject.Parse(get_responseString);

                    //Extracting id from the response of Get request which has to be used in
                    //Post Data when making Post request
                    string name = (string) obj["managedObject"]["id"];

                    //Required JSON Body structure which needs to be merged with Post Data
                    string json2 =    $"{{\"time\": \"{isoTime}\",\"source\": {{\"id\": \"{name}\" 
                    }},\"type\": \"c8y_Golf_Controller\",\"text\": \"PilotCC Data New Msg\"}}";

                    JObject json3 = JObject.Parse(json2);
                    var result = new JObject();
                    result.Merge(item);
                    result.Merge(json3);
                    string json4 = JsonConvert.SerializeObject(result);
                    
                    client.DefaultRequestHeaders.Add("Accept", 
                    "application/vnd.com.nsn.cumulocity.event+json"); //More Headers
                    
                    var stringContent = new StringContent(json4, Encoding.UTF8, 
                    "application/json");
                    
                    stringContent.Headers.ContentType.CharSet = "";

                    //Making Post request                    
                    HttpResponseMessage response = await client.PostAsync("https://myurl.com", 
                    stringContent);

                    var responseString = await response.Content.ReadAsStringAsync();

                    Console.WriteLine(responseString);
                }
          }

     }
        
      public class Root
      {
          public List<Value> Values {get; set;}
      }
      public class Value
      {
          public string RawValue { get; set; }
      }

      public class Station
      {
            [JsonProperty("ControllerName")]
            public string ControllerName { get; set; }

            public override string ToString()
            {
               return String.Format(ControllerName);
            }
      }        
}

如何在每次触发 foreach 循环迭代时不创建不必要的 HttpClient 实例,而是重用 HttpClient 的单个实例来发出所有 http 请求,从而使其变得更好?

回答1

在您的情况下,这足以...

public class Program
{
    static async Task Main()
    {
         // Create one single instance outside the loop ...
         var client = new HttpClient();

         // more code here

         foreach( var item in array ) 
         {
             // ... then use it.
             var response = await client.GetAsync(/* yadda yadda */);
         }
    }
}

相似文章

c# - Xamarin - token 过期时注销

我在Azure上托管了一个Api,我在XamarinForms项目中使用它。我在开头显示登录页面,并检查JWTtoken是否已过期,但我还想检查每个http方法,以防它在用户使用应用程序时过期。所以我...