System.Net.Http.HttpClient 類用於傳送 HTTP 請求以及從 URI 所標識的資源接收 HTTP 響應。 HttpClient 範例是應用於該範例執行的所有請求的設定集合,每個範例使用自身的連線池,該池將其請求與其他請求隔離開來。 從 .NET Core 2.1 開始,SocketsHttpHandler 類提供實現,使行為在所有平臺上保持一致。
HttpClient範例是執行網路請求的設定集合,每個範例會使用一個連線池。通過這段描述我們知道實際使用HttpClient的時候我們只需要範例化一個就行了,在處理程式範例內池連線,並在多個請求之間重複使用連線。也就是官方提倡的使用單個範例,如果每次請求就範例化一個HttpClient,則會建立不必要的連線降低效能,並且TCP 埠不會在連線關閉後立即釋放。
所以如果是大批次建立HttpClient請求則大量負載下可用的通訊端數將耗盡,這種耗盡將導致 SocketException 錯誤。
static readonly HttpClient httpClient = new HttpClient();
public class HttpClientInstance
{
private static readonly HttpClient _HttpClient;
static HttpClientInstance()
{
_HttpClient = new HttpClient();
}
public static HttpClient GetHttpClient()
{
return _HttpClient;
}
}
可以通過構造引數(如 HttpClientHandler (或 SocketsHttpHandler .NET Core 2.1 或更高版本) )作為建構函式的一部分來設定其他選項。 範例化HttpClient後無法更連線屬性,因此,如果需要更改連線屬性,則需要建立新的 HttpClient 範例。
設定可以在構造期間設定 HttpClientHandler 或 SocketsHttpHandler 傳入,SocketsHttpHandler可以設定額外引數包括 MaxConnectionsPerServer, PooledConnectionIdleTimeout、PooledConnectionLifetime、ConnectTimeout。
var handler = new SocketsHttpHandler
{
PooledConnectionLifetime = TimeSpan.FromMinutes(15)
};
var httpClient = new HttpClient(handler);
在.NET Framework 只能使用HttpClientHandler
,且沒有PooledConnectionIdleTimeout和PooledConnectionLifetime等引數。
HttpClientHandler httpClientHandler = new HttpClientHandler();
//最大並行連線數
httpClientHandler.MaxConnectionsPerServer = 100;
HttpClient httpClient=new HttpClient(httpClientHandler);
//超時設定
httpClient.Timeout = new TimeSpan(5000);
可以是設定MaxConnectionsPerServer,可以設定Timeout
。Timeout 為來自 HttpClient 範例的所有 HTTP 請求設定預設超時。 超時僅適用於導致啟動請求/響應的 xxxAsync 方法。 如果達到超時,則會 Task
HttpClient這是一個高階 API,用於包裝其執行的每個平臺上可用的較低階別功能。
在每個平臺上, HttpClient 嘗試使用最佳可用傳輸:
在上面實現可以看到在不同的框架下HttpClient的實現是不一樣的,在.NET Framework下是使用HttpWebRequest
支援。
所以還會受限HttpWebRequest的實現,如果我們要啟用多執行緒高頻率呼叫介面,那麼這裡要注意HttpWebRequest的連線並行的數量限制。HttpWebRequest通過ServicePoint設定,我們通過反編譯看到HttpWebRequest建構函式。
ServicePoint.DefaultConnectionLimit獲取允許的最大並行連線數。 對於 ASP.NET 託管的應用程式,預設連線限制為 10,對於所有其他應用程式,預設連線限制為 2。DefaultConnectionLimit 對現有 ServicePoint 物件沒有影響;它隻影響更改後初始化的物件。如果未直接或通過設定設定此屬性的值,則該值預設為常數 DefaultPersistentConnectionLimit
。
如果是應用連線池預設只有2個並行,所以當你啟用很多執行緒的時候實際效率是不會提升的,一直只有兩個並行在阻塞排隊,如果請求比較耗時後面的請求還有異常的可能。
因此當你使用多執行緒的時候要注意初始化HttpClient的httpClientHandler.MaxConnectionsPerServer = n;
該引數用於設定。
平時我們可能使用RestSharp 用於網路請求,實際也是在HttpWebRequest上的封裝,在官網我們可以看到如下說明:
在最新的v107換成了HttpClient,以前的版本也是HttpWebRequest。如果要設定RestSharp的連線池並行數需要修改預設值。
System.Net.ServicePointManager.DefaultConnectionLimit = n;
然後再範例化RestClient。
作者:SunSpring
出處:https://www.cnblogs.com/SunSpring/p/17148228.html
本文版權歸作者所有,歡迎轉載,但未經作者同意需在文章頁面明顯位置給出原文連結。