C# HTTP客户端:高级请求处理技术

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

C# HTTP客户端:正确发起请求——高级水平



在现代.NET开发中,HTTP请求处理已远远超出简单的WebClient或基础HttpClient调用。在高级水平上,需要考虑连接池管理、正确的错误处理、超时、重试策略以及异步执行。本文将介绍C# HTTP客户端的最佳实践,帮助您创建可靠且高性能的应用程序。



1. 正确使用HttpClient与连接池



最常见的错误之一是为每个请求创建新的HttpClient实例。这会导致套接字耗尽(socket exhaustion),因为每个实例都会保持一个处于TIME_WAIT状态的开放TCP连接。



错误做法:

public async Task<string> GetDataAsync(string url){    using (var client = new HttpClient())    {        return await client.GetStringAsync(url);    }}


正确做法:使用单个静态或单例HttpClient实例。



public class HttpService{    private static readonly HttpClient _client = new HttpClient();

public async Task<string> GetDataAsync(string url) { return await _client.GetStringAsync(url); }}


如需更精细的控制,请使用Microsoft.Extensions.Http包中的IHttpClientFactory。该工厂管理连接池,并在DNS故障时自动恢复连接。



// 在 Startup.cs 或 Program.cs 中services.AddHttpClient("MyClient", client =>{    client.BaseAddress = new Uri("https://api.example.com");    client.DefaultRequestHeaders.Add("User-Agent", "MyApp/1.0");});

// 在服务中public class MyService{ private readonly IHttpClientFactory _httpClientFactory;

public MyService(IHttpClientFactory httpClientFactory) { _httpClientFactory = httpClientFactory; }

public async Task<string> GetDataAsync() { var client = _httpClientFactory.CreateClient("MyClient"); return await client.GetStringAsync("/data"); }}


2. 超时与请求取消



没有超时设置,您的客户端可能会无限期挂起。HttpClient提供两种机制:



  • Timeout — 整个请求的全局超时。
  • CancellationToken — 用于从外部取消请求(例如用户关闭应用程序)。


合理设置Timeout。对于大多数API,10–30秒是合适的。



var client = new HttpClient{    Timeout = TimeSpan.FromSeconds(15)};

// 使用CancellationTokenSource的示例using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));try{ var response = await client.GetAsync("https://slow-api.example.com", cts.Token);}catch (TaskCanceledException){ Console.WriteLine("请求因超时被取消。");}


重要提示: Timeout和CancellationToken协同工作。如果CancellationToken先触发,请求将被更快取消。



3. 错误处理与重试策略



网络故障和服务器临时错误是常见情况。与其直接失败,不如实现带有指数退避的重试策略。Polly库非常适合此目的。



using Polly;using Polly.Extensions.Http;

// 定义重试策略var retryPolicy = HttpPolicyExtensions .HandleTransientHttpError() // 5xx, 408 .Or<HttpRequestException>() .WaitAndRetryAsync(3, retryAttempt => Tim

博客

书籍推荐