Reputation: 93
I have a code where I am creating an instance of HttpClient
, which is inside of a foreach loop. 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??
Upvotes: 2
Views: 2034
Reputation: 16104
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 */);
}
}
}
Upvotes: 3