简体   繁体   English

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

[英]How to reuse HttpClient reference for multiple http requests

I have a code where I am creating an instance of HttpClient , which is inside of a foreach loop.我有一个代码,我在其中创建HttpClient的实例,该实例位于 foreach 循环内。 Which means it is creating a new instance for each time the iteration takes place.这意味着每次迭代发生时它都会创建一个新实例。 Here is my code :这是我的代码:

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);
            }
      }        
}

How do I make it better by not creating unnecessary instances of HttpClient each time foreach loop iteration in triggered and instead reuse the single instance of HttpClient for making all the http requests??如何在每次触发 foreach 循环迭代时不创建不必要的 HttpClient 实例,而是重用 HttpClient 的单个实例来发出所有 http 请求,从而使其变得更好?

In your case, it would be enough to ...在您的情况下,这足以...

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 */);
         }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM