После прочтения сообщений ниже о рекомендуемом использовании HttpClient
, я изменил свой код на экземпляр HttpClient
на запрос в рамках используемого блока на долгоживущий объект ,Настройка HttpClient в .NET, чтобы она работала с несколькими потоками и обеспечивала параллелизм
Do HttpClient and HttpClientHandler have to be disposed?
What is the overhead of creating a new HttpClient per call in a WebAPI client?
Моя реализация является частью API низкого уровня, и будет делать запросы из разных частей приложения, работающие на разных потоках, поэтому потокобезопасность и параллелизм при запросы на запросы также должны быть гарантированы.
Я даже продолжал делать это синглтон, как показано ниже, поэтому есть только один экземпляр HttpClient, используемый во всем приложении. (Статья четвертой формы версии Джона Скита)
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;
}
}
}
И ниже приведен пример того, как это привыкает
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
}
}
При выполнении запросов через HttpClient
, я удостоверился, чтобы использовать только перечисленные ниже безопасные методы, но при десериализации ответа используется result.Content.ReadAsStringAsync().Result
. Это связано с тем, что вызовы более высокого уровня еще не поддерживают асинхронные ответы.
https://msdn.microsoft.com/en-us/library/system.net.http.httpclient(v=vs.110).aspx#Anchor_5
Однако, я до сих пор есть несколько вопросов.
- Является ли этот подход надежным и стабильным потоком, чтобы не вызвать утечек памяти?
- Как настроить таймаут для каждого запроса?
- Нужно ли указывать 'Connection: keep-alive' в DefaultHeaders?
- Как добавить пользовательский заголовок/изменить заголовок по умолчанию для каждого запроса?
- И, наконец, Существуют ли какие-либо известные проблемы с производительностью/недостатки в использовании HttpClient таким образом?