As a software developer, I once confidently set HttpClient.Timeout, and assumed my API calls would be under control. Instead, the call hung forever. That’s when I realized timeouts can be sneaky—and setting them isn’t enough unless you really understand how they work.
The Problem
I wrote:
httpClient.Timeout = TimeSpan.FromSeconds(10);
await httpClient.GetAsync("https://example.com/api");
But the request never timed out. No exception, just silence. It turns out that HttpClient.Timeout doesn’t guarantee a timeout in every scenario, and hanging calls are far too common.
The Solution
The turning point came when I used a CancellationToken:
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
await httpClient.GetAsync("https://example.com/api", cts.Token);
Now, the call always cancels after 10 seconds, throwing a TaskCanceledException. This gives me control over failures and ensures my app doesn’t hang indefinitely.
Deeper Explanation
Why didn’t the timeout alone work? According to Microsoft:
A Domain Name System (DNS) query may take up to 15 seconds to return or time out. If your request contains a host name that requires resolution and you set Timeout to a value less than 15 seconds, it may take 15 seconds or more before a WebException is thrown…
In short: DNS lookups (and some socket behaviour) bypass the Timeout setting. Only a CancellationToken enforces a deadline reliably at the lower networking layers. Plus, if you reuse HttpClient, a global Timeout may cause unwanted side effects. Per-call tokens are clearer and safer.
Best Practices
- Use
CancellationTokenSourcewith a timeout per request—never rely solely onHttpClient.Timeout. - Wrap calls in
try/catch(TaskCanceledException)to gracefully handle timeouts. - Reuse
HttpClientviaIHttpClientFactory, but manage timeouts on every call. - Log timeout events along with their durations to assist debugging and monitoring.
Conclusion
Setting HttpClient.Timeout might prevent some hangs, but it doesn’t cover all edge cases—especially DNS or low-level socket issues. The real hero is an explicit CancellationToken. So, next time you need reliable timeouts, be explicit: pass in a timed token and take back control.
Happy coding—and may your API calls always be responsive!





Leave a Reply