我有一个代码,我在其中创建 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 */);
}
}
}