After reading the posts below about recommended usage of HttpClient
, I changed my code from instantiating HttpClient
per request within a using block to a long-lived object.
Do HttpClient and HttpClientHandler have to be disposed?
What is the overhead of creating a new HttpClient per call in a WebAPI client?
My implementation is part of a low-level api, and would be to make requests from from different parts of the app running on different threads, so thread-safety and concurrency when making requests needs to be guaranteed as well.
I even went on to make it a singleton as below, so there is just one instance of HttpClient used throughout the app. (fourth version form John SKeet's article)
http://csharpindepth.com/Articles/General/Singleton.aspx
public sealed class MyHttpClient
{
private static readonly volatile HttpClient _myHttpClient = new HttpClient();
static MyHttpClient() {}
private MyHttpClient(){ }
public static HttpClient MyHttpClientObj
{
get
{
return _myHttpClient;
}
}
}
And below is an example of how this gets used
public IEnumerable<string> GetSomeData(string url, FormUrlEncodedContent bodyParameters)
{
try
{
//is it possible to configure timeout here instead, such that every request will have its one timeout duration?
var response = MyHttpClient.MyHttpClientObj.PostAsync(url, bodyParameters);
var result = response.Result;
if (!result.IsSuccessStatusCode)
{
//log and return null
}
var data = JsonConvert.DeserializeObject<List<string>>(result.Content.ReadAsStringAsync().Result);
return data;
}
catch (Exception ex)
{
//logging exceptions
}
}
When making requests via HttpClient
, I've made sure to use only the therad-safe methods listed below, but when deserializing the response, result.Content.ReadAsStringAsync().Result
is used. This is because the higher level calls don't support async responses yet.
https://msdn.microsoft.com/en-us/library/system.net.http.httpclient(v=vs.110).aspx#Anchor_5
However, I still have a few questions.
- Is this approach Thread-safe and stable enough to not cause any memory leaks?
- How can I configure the Timeout for every request?
- Is it necessary to specify 'Connection: keep-alive' in DefaultHeaders?
- How can I add a custom header/modify a default header for every request?
- And finally, Are there any known performance issues/drawbacks in using HttpClient this way?