因為所寫的 C# 程式需要由網路下載大的檔案,但官方文件所寫的內容不夠多,所以花了點時間,研究了 HttpClient 非同步下載,並且記錄了一些資料,以供自己未來複習及提供有需要的人參考。
WebClient vs HttpClient
在微軟官方文件中,一開始有找到了 WebClient 和 HttpClient 二種類別,結果在 WebClient 的官方文件中,看到這一段:
我們不建議您將類別用於 WebClient 新的開發。 請改用 System.Net.Http.HttpClient 類別。
所以就放棄研究 WebClient,直攻 HttpClient 了。
HttpClient 及注意事項
HttpClient 雖然比 WebClient 好用,但有一些事要注意。
首先是不要大量使用新建立的 HttpClient,底下是官方文件的說明:
HttpClient 的目的是要具現化一次,並在應用程式的整個生命週期中重複使用。具現化每個要求的 HttpClient 類別,將會耗盡繁重負載下可用的通訊端數目。這會導致 >socketexception 錯誤。以下是正確使用 HttpClient 的範例。
public class GoodController : ApiController
{
private static readonly HttpClient HttpClient;
static GoodController()
{
HttpClient = new HttpClient();
}
}
不過,在實測中,最多同時只能開啟二個連結。
查了不少資料,才知道有個變數 ServicePointManager.DefaultConnectionLimit,官方說明:
ServicePoint 物件所允許的同時連線最大數。 ASP.NET 裝載的應用程式預設的連線限制為10,其他則為2。
所以若要多開啟幾個連結,不知如何做才好?目前我只找到二個方法:
1. 增加 ServicePointManager.DefaultConnectionLimit
2. HttpClient 每次都建立新物件,就沒這個問題了。
在網路上也查詢了其它文章,有人提到若用 static 的方式來執行 HttpClient ,也會有一些限制,例如長期連線時,可能因為網路上的 DNS 更新後,HttpClient 沒有更新解析 DNS,就會有問題。
因此有人介紹更好用的 HttpClientFactory,不過官方文件我只有查到 IHttpClientFactory,而且看起來有點複雜,反正我目前的程式不會用到大量的連線,也不會需要長時間使用,不用擔心 DNS 更新的問題,所以決定還是使用 HttpClient 即可。
另外,官方還有這個建議:
想要下載大量資料 (50 mb 或以上的) ,則應用程式應該串流這些下載,而不使用預設的緩衝。如果使用預設緩衝,用戶端記憶體使用量將會變得非常大,可能會大幅降低效能。
這也是我需要測試的,因為我需要下載的檔案會有超過 GB 的大小。