Как изменить таймаут для конкретного запроса в HttpClient?



Одной из лучших практик по работе с HttpClient в C# считается переиспользование одного экземпляра клиента для множества запросов. Как минимум во избежание port exhaustion.



Однако, возникают ситуации, когда для разных запросов требуется разное поведение клиента. Например, разные таймауты.



Проблема в том, что HttpClient.Timeout устанавливается единожды, во время создания клиента. И несмотря на наличие public set'тера, это значение не может быть изменено впоследствии. Любые попытки пресекаются выбрасыванием InvalidOperationException.



Но я бы не писал этот пост, если бы не существовало решения проблемы. А решение довольно простое:

TimeSpan timeout = GetMyTimeout();

using (var tokenSource = new CancellationTokenSource(timeout))

{

var response = await httpClient.GetAsync(uri, tokenSource.Token);

HandleResponse(response);

}





Такое решение можно не только использовать "в лоб", но и обернуть в пайплайн из DelegatingHandler'ов. Для того чтобы оно работало, потребуется убедиться в двух вещах:



1️⃣ Пользовательский таймаут меньше того, что установлен в HttpClient.Timeout



2️⃣ Пользовательский таймаут валиден. Проще говоря, время ожидания больше 0 секунд.