.Net下使用HttpClient实现进度条效果
99
2023-10-05
从.Net6开始,WebRequest就已被标识已过时,微软推荐使用HttpClient
进行替代。在查阅了相关文档后,整理了一个在HttpClient上实现进度条效果的下载封装。
PS:目前测试结果,当网络环境处于特殊代理环境下时(如clash代理),HttpCompletionOption.ResponseHeadersRead
不被支持,推测可能是代理转发存在某些缺陷造成。
/// <summary>
/// 下载文件
/// </summary>
/// <param name="fullFileName">保存路径</param>
/// <param name="url">资源地址</param>
/// <param name="callback">回调</param>
/// <param name="progress">进度</param>
/// <returns></returns>
public static async Task<bool> DownloadAsync(string fullFileName, string url, Action<bool, string> callback, Action<int> progress)
{
if (File.Exists(fullFileName))
File.Delete(fullFileName);
try
{
using (var client = new System.Net.Http.HttpClient())
{
// HttpCompletionOption.ResponseHeadersRead
// 即得到header后就响应结果,不必等待内容,也是实现进度效果的核心代码
using (var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
{
response.EnsureSuccessStatusCode();
var length = response.Content.Headers.ContentLength;
long readLength = 0;
using (var responseStream = await response.Content.ReadAsStreamAsync())
{
using (var stream = new FileStream(fullFileName, FileMode.Create))
{
byte[] byteArry = new byte[1024];
int size = responseStream.Read(byteArry, 0, (int)byteArry.Length);
readLength += size;
while (size > 0)
{
stream.Write(byteArry, 0, size);
if (progress != null)
progress((int)(readLength * 100 / length));
size = responseStream.Read(byteArry, 0, (int)byteArry.Length);
readLength += size;
}
}
}
}
}
if (callback != null)
callback(true, fullFileName);
return true;
}
catch (Exception ex)
{
if (callback != null)
callback(false, ex.Message);
return false;
}
}
- 1
- 1
-
分享