IConfiguration vs IOptions NET
Synchronous and Asynchronous in .NET Core
Model Binding and Validation in ASP.NET Core
ControllerBase vs Controller in ASP.NET Core
ConfigureServices and Configure methods
IHostedService interface in .NET Core
ASP.NET Core request processing
| Reverse Proxy :👈 | 👉:Reverse Proxy vs API Gateway |
Socket Exhaustion |
Socket Exhaustion occurs when an application creates too many network connections (sockets) and doesn't release or reuse them efficiently. Eventually, the operating system runs out of available sockets (or ephemeral ports), causing new HTTP requests to fail.
A very common cause in .NET is creating a new HttpClient object for every request.
public async Task<string> GetData()
{
using (var client = new HttpClient())
{
return await client.GetStringAsync(
"[https://api.example.com/data](https://api.example.com/data)");
}
}
Looks harmless, but if this method executes thousands of times:
for(int i = 0; i < 10000; i++)
{
await GetData();
}
many TCP connections are created.
Even after HttpClient is disposed, the underlying TCP connections may remain in the TIME_WAIT state for some time.
Many sockets remain in TIME_WAIT
Eventually:
System.Net.Http.HttpRequestException or Only one usage of each socket address (network address/port) is normally permitted.
When a TCP connection closes:
Client -------- Server FIN ------> <------ ACK
the socket does not disappear immediately. The OS keeps it in:TIME_WAIT to ensure all packets are delivered properly. If thousands of connections are opened and closed rapidly:5000+ sockets in TIME_WAIT new connections cannot be created.
public class ApiService
{
private static readonly HttpClient _client =
new HttpClient();
public async Task<string> GetData()
{
return await _client.GetStringAsync(
"[https://api.example.com/data](https://api.example.com/data)");
}
}
Benefits:
In ASP.NET Core, Microsoft recommends IHttpClientFactory.
builder.Services.AddHttpClient();
public class WeatherService
{
private readonly HttpClient _client;
public WeatherService(
IHttpClientFactory factory)
{
_client = factory.CreateClient();
}
public async Task<string> GetWeather()
{
return await _client.GetStringAsync(
"[https://api.weather.com](https://api.weather.com)");
}
}
IHttpClientFactory:
builder.Services.AddHttpClient(
"GitHub",
client =>
{
client.BaseAddress =
new Uri("[https://api.github.com](https://api.github.com)");
client.DefaultRequestHeaders.Add(
"User-Agent",
"MyApp");
});
Use:
public class GitHubService
{
private readonly HttpClient _client;
public GitHubService(
IHttpClientFactory factory)
{
_client = factory.CreateClient(
"GitHub");
}
}
Imagine an ASP.NET Core API receives:
1000 requests/minute
and for every request:
using var client = new HttpClient();
After a short period:
Thousands of sockets accumulate. Users then see:
builder.Services.AddHttpClient<IMyApiService,
MyApiService>(client =>
{
client.BaseAddress =
new Uri("[https://api.example.com](https://api.example.com)");
client.Timeout =
TimeSpan.FromSeconds(30);
});
public class MyApiService : IMyApiService
{
private readonly HttpClient _httpClient;
public MyApiService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<string> GetData()
{
return await _httpClient.GetStringAsync(
"/users");
}
}
This is the recommended production approach in modern ASP.NET Core applications.
Socket Exhaustion is a condition where an application creates and disposes many network connections too quickly, causing available TCP sockets/ports to be exhausted. In .NET, it commonly happens when
HttpClientis instantiated per request. The solution is to reuseHttpClientinstances or useIHttpClientFactory, which manages connection pooling efficiently and prevents socket exhaustion.
| Reverse Proxy :👈 | 👉:Reverse Proxy vs API Gateway |