dra*_*ons 0 c# dotnet-httpclient polly
我有一个.tgz文件,我需要下载一个Testing文件夹内的 url 。我可以.tgz使用 .url 从 url 成功下载文件WebClient。
下面是我的代码:
private void DownloadTGZFile(string url, string fileToDownload)
{
using (var client = new WebClient())
{
client.DownloadFile(url + fileToDownload, "Testing/configs.tgz");
}
}
Run Code Online (Sandbox Code Playgroud)
我想看看如何为这个调用添加超时,以便如果 url 在特定时间内没有响应,那么它应该超时但它可以重试 3 次然后放弃。另外我想看看我如何HttpClient在这里使用而不是WebClient考虑它是一个较旧的 BCL 类而不推荐。
要下载文件,HttpClient您可以执行以下操作:
// Is better to not initialize a new HttpClient each time you make a request,
// it could cause socket exhaustion
private static HttpClient _httpClient = new HttpClient()
{
Timeout = TimeSpan.FromSeconds(5)
};
public async Task<byte[]> GetFile(string fileUrl)
{
using (var httpResponse = await _httpClient.GetAsync(fileUrl))
{
// Throws an exception if response status code isn't 200
httpResponse.EnsureSuccessStatusCode();
return await httpResponse.Content.ReadAsByteArrayAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,要为Http调用定义超时,您应该在创建新的HttpClient.
要为之前的代码实施重试策略,我将安装Polly NuGet 包,然后:
public async Task<byte[]> GetFile(string fileUrl)
{
return await Policy
.Handle<TaskCanceledException>() // The exception thrown by HttpClient when goes in timeout
.WaitAndRetryAsync(retryCount: 3, sleepDurationProvider: i => TimeSpan.FromMilliseconds(300))
.ExecuteAsync(async () =>
{
using (var httpResponse = await _httpClient.GetAsync(fileUrl))
{
// Throws an exception if response status code isn't 200
httpResponse.EnsureSuccessStatusCode();
return await httpResponse.Content.ReadAsByteArrayAsync();
}
});
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我定义了 3 次重试,每次尝试之间的间隔为 300 毫秒。另请注意,我没有为每种 定义重试Exception,因为如果 - 例如 - 你输入了一个无效的URL,重试是无稽之谈。
最后,如果你想将该字节数组保存到一个文件中,你可以这样做:
File.WriteAllBytes(@"MyPath\file.extension", byteArray);
Run Code Online (Sandbox Code Playgroud)