Динамическое изменение HttpClient.Timeout в .NET.
Мне нужно изменить свойство HttpClient.Timeout
после запроса (-ов) запроса. Когда я пытаюсь, я получаю исключение:
Этот экземпляр уже запустил один или несколько запросов. Свойства могут быть изменены только перед отправкой первого запроса.
Есть ли способ избежать этого?
Ответы
Ответ 1
Вы не можете сделать это, чтобы изменить это. Это просто поведение по умолчанию в реализации HttpClient.
Свойство Timeout должно быть установлено до вызова метода GetRequestStream или GetResponse. Из раздела HttpClient.Timeout Remark
Чтобы изменить таймаут, было бы лучше создать новый экземпляр HttpClient.
client = new HttpClient();
client.Timeout = 20; //set new timeout
Ответ 2
Внутренне свойство Timeout
используется для установки a CancellationTokenSource
, который прервет операцию async, когда этот тайм-аут будет достигнут. Поскольку некоторые перегрузки методов HttpClient
принимают CancellationTokens
, мы можем создавать вспомогательные методы для получения пользовательских тайм-аутов для определенных операций:
public async Task<string> GetStringAsync(string requestUri, TimeSpan timeout)
{
using (var cts = new CancellationTokenSource(timeout))
{
HttpResponseMessage response = await _httpClient.GetAsync(requestUri, cts.Token)
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
}
Ответ 3
Отсутствие поддержки пользовательских тайм-аутов на уровне запросов всегда было недостатком HttpClient
, на мой взгляд. Если вы не возражаете против небольшой зависимости от библиотеки, Flurl.Http [отказ от ответственности: я автор] поддерживает это напрямую:
"http://api.com/endpoint".WithTimeout(30).GetJsonAsync<T>();
Это истинный параметр уровня запроса; все вызовы одного и того же хоста используют общий экземпляр HttpClient
под капотом, а одновременные вызовы с разными тайм-аутами не будут конфликтовать. Там настраивается глобальное значение по умолчанию (сначала 100 секунд, так же как HttpClient
).