C#實(shí)現(xiàn)Http請求的多種方案
更新時間:2025年07月24日 11:02:18 作者:code_shenbing
在現(xiàn)代應(yīng)用中,HTTP 請求是與 API 服務(wù)交互的核心方式,本文將系統(tǒng)講解 C# 實(shí)現(xiàn) HTTP 請求的多種方案,涵蓋從基礎(chǔ)用法到企業(yè)級高性能實(shí)踐(支持 .NET 5+),需要的朋友可以參考下
一、基礎(chǔ) HTTP 請求方法
1. ??HttpClient 基礎(chǔ)用法?
// GET 請求示例
async Task<string> GetDataAsync(string url)
{
using var httpClient = new HttpClient();
HttpResponseMessage response = await httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
// POST 請求示例
async Task PostDataAsync(string url, object data)
{
using var httpClient = new HttpClient();
var json = JsonSerializer.Serialize(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync(url, content);
response.EnsureSuccessStatusCode();
}警告:不要每次請求創(chuàng)建新 HttpClient!這會導(dǎo)致:
- 端口耗盡 (TIME_WAIT 狀態(tài))
- DNS 更新延遲
- 連接池?zé)o法復(fù)用
二、高性能 HTTP 客戶端實(shí)踐
1. ??IHttpClientFactory 最佳實(shí)踐?
// 1. Startup 注冊服務(wù)
services.AddHttpClient("FinanceAPI", client => {
client.BaseAddress = new Uri("https://api.finance.com");
client.Timeout = TimeSpan.FromSeconds(15);
client.DefaultRequestHeaders.Add("Accept", "application/json");
});
// 2. 控制器中使用
public class DataController : Controller
{
private readonly IHttpClientFactory _factory;
public DataController(IHttpClientFactory factory) => _factory = factory;
public async Task<IActionResult> GetStockData()
{
var client = _factory.CreateClient("FinanceAPI");
var response = await client.GetAsync("/stocks/MSFT");
// ...
}
}2. ??HTTP/2 連接復(fù)用?
var handler = new SocketsHttpHandler
{
PooledConnectionLifetime = TimeSpan.FromMinutes(5),
EnableMultipleHttp2Connections = true
};
var client = new HttpClient(handler)
{
DefaultRequestVersion = HttpVersion.Version20,
DefaultVersionPolicy = HttpVersionPolicy.RequestVersionExact
};3. ??流式處理大響應(yīng)?
// 避免大響應(yīng)阻塞內(nèi)存
async Task ProcessLargeResponse(string url)
{
using var client = new HttpClient();
using var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
using var stream = await response.Content.ReadAsStreamAsync();
await using var buffer = new BufferedStream(stream);
using var reader = new StreamReader(buffer);
while (!reader.EndOfStream)
{
var line = await reader.ReadLineAsync();
ProcessLine(line); // 逐行處理
}
}三、高級場景實(shí)現(xiàn)
1. ??自定義重試策略?
// 指數(shù)退避重試器
async Task<T> ExecuteWithRetry<T>(Func<Task<T>> action, int maxRetries = 3)
{
int retryCount = 0;
while (true)
{
try
{
return await action();
}
catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.TooManyRequests)
{
if (retryCount++ >= maxRetries) throw;
var delay = TimeSpan.FromSeconds(Math.Pow(2, retryCount));
await Task.Delay(delay);
}
}
}
// 使用示例
var data = await ExecuteWithRetry(() => GetDataAsync("https://unstable-api.com/data"));2. ??動態(tài)請求頭簽名?
// 安全 API 調(diào)用簽名
async Task SendSignedRequest(string url)
{
var handler = new CustomSignatureHandler();
var client = new HttpClient(handler);
// ... 正常調(diào)用
}
class CustomSignatureHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancelToken)
{
// 1. 獲取時間戳
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
// 2. 生成簽名
var signData = $"{request.Method}{request.RequestUri}{timestamp}{API_SECRET}";
var signature = HMACSHA256.Hash(signData);
// 3. 添加安全頭
request.Headers.Add("X-Timestamp", timestamp.ToString());
request.Headers.Add("X-Signature", Convert.ToBase64String(signature));
return await base.SendAsync(request, cancelToken);
}
}四、性能優(yōu)化策略
1. 連接管理優(yōu)化
| ??參數(shù)?? | ??推薦值?? | ??作用?? |
|---|---|---|
| MaxConnectionsPerServer | 50-100 | 控制單個主機(jī)最大連接數(shù) |
| PooledConnectionIdleTimeout | 1-2 分鐘 | 空閑連接保持時間 |
| PooledConnectionLifetime | 5-10 分鐘 | 連接最大存活時間 |
2. 響應(yīng)處理優(yōu)化技巧
// 高效 JSON 反序列化
async Task<T> ParseJsonResponse<T>(HttpResponseMessage response)
{
// 使用流式 API 避免大對象分配
await using var stream = await response.Content.ReadAsStreamAsync();
return await JsonSerializer.DeserializeAsync<T>(stream, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
DefaultBufferSize = 8192 // 8KB 緩沖區(qū)
});
}
// 使用 ArrayPool 處理二進(jìn)制響應(yīng)
async Task ProcessBinaryResponse(string url)
{
var response = await _httpClient.GetAsync(url);
var buffer = ArrayPool<byte>.Shared.Rent(1024 * 64);
try
{
await using var stream = await response.Content.ReadAsStreamAsync();
int bytesRead;
while ((bytesRead = await stream.ReadAsync(buffer)) > 0)
{
ProcessChunk(new ReadOnlySpan<byte>(buffer, 0, bytesRead));
}
}
finally
{
ArrayPool<byte>.Shared.Return(buffer);
}
}五、常見問題解決方案
1. DNS 更新問題
// 強(qiáng)制刷新 DNS 緩存
var handler = new SocketsHttpHandler
{
PooledConnectionLifetime = TimeSpan.FromMinutes(5), // 設(shè)置連接生命周期
PooledConnectionIdleTimeout = TimeSpan.FromSeconds(30)
};2. 證書驗(yàn)證處理
// 開發(fā)環(huán)境忽略證書錯誤(生產(chǎn)環(huán)境禁用?。?
var handler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (_, _, _, _) => true
};3. 多部分表單上傳
async Task UploadFile(string url, string filePath)
{
using var content = new MultipartFormDataContent();
using var fileStream = File.OpenRead(filePath);
content.Add(new StreamContent(fileStream), "file", "data.zip");
content.Add(new StringContent("2024-report"), "description");
var response = await _httpClient.PostAsync(url, content);
response.EnsureSuccessStatusCode();
}六、性能監(jiān)控與診斷
1. HttpClient 指標(biāo)監(jiān)控
# 查看連接池狀態(tài) dotnet-counters monitor -n MyApp System.Net.Http
2. 請求跟蹤
// 添加日志記錄器
services.AddHttpClient("LoggingClient")
.ConfigurePrimaryHttpMessageHandler(() => new LoggingHandler(new SocketsHttpHandler()));
class LoggingHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
var stopwatch = Stopwatch.StartNew();
try
{
return await base.SendAsync(request, cancellationToken);
}
finally
{
_logger.LogInformation($"{request.Method} {request.RequestUri} took {stopwatch.ElapsedMilliseconds}ms");
}
}
}最佳實(shí)踐總結(jié)??:
- ??連接管理??:始終重用
HttpClient,通過工廠管理生命周期 - ??協(xié)議選擇??:啟用 HTTP/2 提升并發(fā)性能(尤其在高延遲網(wǎng)絡(luò))
- ??資源控制??:流式處理響應(yīng),避免大內(nèi)存分配
- ??彈性策略??:實(shí)現(xiàn)重試/熔斷機(jī)制(推薦使用 Polly)
- ??監(jiān)控保障??:持續(xù)跟蹤請求延遲和錯誤率

??性能對比??:
| ??場景?? | 原始方式 | 優(yōu)化方式 | 提升幅度 |
|---|---|---|---|
| 1000次連續(xù)請求 | 28秒 | 9.2秒 | 3倍 |
| 10MB JSON 響應(yīng) | 1.2秒 | 0.4秒 | 3倍 |
| 高并發(fā)連接 | 350 QPS | 1200 QPS | 3.4倍 |
以上就是C#實(shí)現(xiàn)Http請求的多種方案的詳細(xì)內(nèi)容,更多關(guān)于C#實(shí)現(xiàn)Http請求的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Unity游戲開發(fā)中的中介者模式的應(yīng)用與實(shí)現(xiàn)
中介者模式是Unity游戲開發(fā)中常用的設(shè)計模式之一,用于減少對象之間的直接耦合,通過引入中介者來協(xié)調(diào)對象之間的交互。通過中介者模式,游戲?qū)ο罂梢愿屿`活地進(jìn)行交互和協(xié)同工作,降低系統(tǒng)復(fù)雜度,使代碼更加易于維護(hù)和擴(kuò)展2023-05-05
使用C#實(shí)現(xiàn)上位機(jī)與PLC通信的過程詳解
隨著工業(yè)自動化技術(shù)的不斷發(fā)展,PLC(可編程邏輯控制器)已成為現(xiàn)代生產(chǎn)過程中不可或缺的設(shè)備,為了實(shí)現(xiàn)設(shè)備之間的數(shù)據(jù)交換和遠(yuǎn)程控制,上位機(jī)系統(tǒng)需要與PLC進(jìn)行通信,在本文中,我們將從零開始,介紹如何使用C#實(shí)現(xiàn)上位機(jī)與PLC的通信,需要的朋友可以參考下2025-01-01
C#中List轉(zhuǎn)IList的實(shí)現(xiàn)
本文主要介紹了C#中List轉(zhuǎn)IList的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
C#影院售票系統(tǒng)畢業(yè)設(shè)計(2)
這篇文章主要介紹了C#影院售票系統(tǒng)畢業(yè)設(shè)計,介紹了電影院座位的動態(tài)繪制、電影信息綁定到窗體中如何展現(xiàn)出來,需要的朋友可以參考下2015-11-11
C#實(shí)現(xiàn)多線程的幾種方式小結(jié)
多線程是C#中一個重要的概念,多線程指的是在同一進(jìn)程中同時運(yùn)行多個線程的機(jī)制,多線程適用于需要提高系統(tǒng)并發(fā)性、吞吐量和響應(yīng)速度的場景,可以充分利用多核處理器和系統(tǒng)資源,提高應(yīng)用程序的性能和效率,本文介紹了C#實(shí)現(xiàn)多線程的幾種方式,需要的朋友可以參考下2024-07-07

