v1.10.82-f67ee7d
Skip to main content
← Back to Code Snippets

C# HttpClient Proxy

Complete HttpClient proxy integration example for C# with Hex Proxies. Includes authentication, timeouts, and error handling.

C#HttpClient
Install:dotnet new console (built-in System.Net.Http)
C# / HttpClient
using System.Net;
using System.Net.Http;

var proxy = new WebProxy("http://gate.hexproxies.com:8080")
{
    Credentials = new NetworkCredential("user", "pass"),
};

var handler = new HttpClientHandler
{
    Proxy = proxy,
    UseProxy = true,
};

using var client = new HttpClient(handler)
{
    Timeout = TimeSpan.FromSeconds(30),
};

try
{
    var response = await client.GetStringAsync("https://httpbin.org/ip");
    Console.WriteLine($"Response: {response}");
}
catch (HttpRequestException ex)
{
    Console.WriteLine($"Request failed: {ex.Message}");
}
catch (TaskCanceledException)
{
    Console.WriteLine("Request timed out");
}

Why C# for Proxy Work

C# and the .NET platform provide a unique combination of high performance, strong typing, and enterprise-grade tooling that makes them well-suited for production proxy integrations. The .NET runtime's ahead-of-time compilation (NativeAOT in .NET 8+), efficient garbage collector, and optimized networking stack deliver throughput comparable to Go and Rust while maintaining the developer productivity of a managed language. For organizations already invested in the Microsoft ecosystem, C# proxy integrations plug directly into ASP.NET Core web services, Azure Functions, and Windows services without introducing new languages or runtime dependencies.

The `System.Net.Http` namespace, included in every .NET installation since .NET Core 1.0, provides a mature HTTP client stack with native proxy support, connection pooling, and HTTP/2 capabilities. Unlike dynamic languages where proxy libraries may have subtle compatibility issues across runtime versions, C#'s compiled nature catches configuration errors at build time. The `HttpClient` class is designed for long-lived reuse and internally manages connection pools to gate.hexproxies.com:8080, making it efficient for high-volume proxy workloads.

Configuration Patterns

C# separates proxy configuration into three layers. The `WebProxy` object encapsulates the proxy address, credentials, and bypass rules. The `HttpClientHandler` connects the proxy to the HTTP pipeline and provides TLS settings, cookie management, and redirect behavior. The `HttpClient` wraps everything with timeout configuration and a high-level request API. This layered design allows you to swap proxy configurations without rebuilding the entire client stack.

In ASP.NET Core applications, use `IHttpClientFactory` to manage `HttpClient` lifetimes and proxy configuration. Register a named client with proxy settings in `Startup.ConfigureServices()` using `services.AddHttpClient("proxied", client => { ... }).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { Proxy = proxy })`. The factory handles connection pool management, DNS refresh, and handler lifecycle, preventing the socket exhaustion issues that plague manually created HttpClient instances.

Common Pitfalls

The most impactful mistake in C# proxy code is creating and disposing `HttpClient` instances per request. Despite implementing `IDisposable`, HttpClient is designed for reuse. Each new instance creates a new connection pool with fresh DNS resolution and TCP connections, and the disposed instance's sockets linger in TIME_WAIT state for up to 240 seconds. In a proxy workload making hundreds of requests per second, this rapidly exhausts available sockets and causes `SocketException` errors. Use a single HttpClient instance or IHttpClientFactory.

`TaskCanceledException` in C# serves double duty for both user-initiated cancellation and timeout expiration, which makes proxy timeout detection ambiguous. When catching this exception, check `ex.CancellationToken.IsCancellationRequested` to distinguish between a timeout (where it is false) and a cancellation (where it is true). In .NET 5+, timeout-caused cancellations throw `TaskCanceledException` with an inner `TimeoutException`, making the distinction clearer but still requiring attention.

Performance Optimization

.NET 6+ introduced the `SocketsHttpHandler` as the default handler, replacing `HttpClientHandler` with a more efficient implementation that provides fine-grained control over connection pooling. Set `PooledConnectionLifetime` to rotate proxy connections periodically (prevents stale connections), `MaxConnectionsPerServer` to control concurrency to the proxy gateway, and `PooledConnectionIdleTimeout` to reclaim unused connections. These settings directly affect proxy throughput and resource utilization.

For maximum concurrency, use `Task.WhenAll()` with a `SemaphoreSlim` to control parallelism. Launch hundreds of proxied requests as tasks, bounded by the semaphore to match your proxy allocation's capacity. The async/await pattern in C# is zero-allocation for synchronous completions and uses efficient state machines for asynchronous continuations, making it competitive with Go's goroutines for I/O-bound proxy workloads. Profile with `dotnet-trace` and `dotnet-counters` to monitor HTTP connection pool utilization and identify bottlenecks.

Tips

  • 1
    Reuse HttpClient instances to avoid socket exhaustion.
  • 2
    Use IHttpClientFactory in ASP.NET Core for proper lifecycle management.
  • 3
    Catch TaskCanceledException to handle timeouts separately from other errors.

Ready to Integrate?

Get proxy credentials and start coding in minutes.