c# - 如果连接断开,HttpClient 下载会卡住
问题描述
我正在使用 HttpClient 在 C# 应用程序(.NET Framework 4.6.1)中下载文件。
下面代码的问题是,如果在下载过程中连接断开,代码会卡在 CopyToAsync 方法上。
如果我使用 WebClient.DownloadFileAsync 方法,我会遇到同样的问题,但我想改用 HttpClient。
public class DownloadManager
{
private readonly HttpClientHandler _handler;
private readonly HttpClient _client;
public DownloadManager()
{
_handler = new HttpClientHandler();
_client = new HttpClient(_handler);
}
public async Task Download(string url, string file, CancellationToken cancellationToken)
{
try
{
var response = await _client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
if (response.IsSuccessStatusCode)
{
using (var fileStream = new FileStream(file, FileMode.Create, FileAccess.Write))
{
var stream = await response.Content.ReadAsStreamAsync();
await stream.CopyToAsync(fileStream, 81920, cancellationToken);
}
}
}
catch (Exception ex)
{
if (cancellationToken.IsCancellationRequested)
{
throw new Exception("Download was cancelled");
}
throw ex;
}
}
}
解决方案
您必须设置ReadTimeout
从. 默认设置为(5 分钟)。Stream
HttpClient
ReadTimeout
300_000
using (var fileStream = new FileStream(file, FileMode.Create, FileAccess.Write))
{
var stream = await response.Content.ReadAsStreamAsync();
// stream.CanTimeout -> this returns true
stream.ReadTimeout = 1000; // ReadTimeout takes number of milliseconds
await stream.CopyToAsync(fileStream, 81920, cancellationToken);
}
这仅适用于 .NET Framework。该stream.CanTimeout
属性false
在 .NET Core 上返回。
推荐阅读
- php - 在 switch 语句 PHP 中使用链接
- bash - 如何通过 gcloud 计算在远程 GCP 机器上运行本地 shell 脚本?
- pandas - 根据现有数据框中的值计算小于另一个数据框中的值
- flutter - '列表
' 不是类型 'List 的子类型 ' 在类型转换中 - javascript - 如何将ejs数据传递给javascript变量?
- php - Codeigniter 无法登录家庭管理员
- javascript - 如何通过缩小字体大小在 1 行文本区域中动态调整文本?
- c# - 使用 newtonsoft 的 json 结构的序列化问题
- r - R中零膨胀负二项式的系数与glm之间的不一致
- javascript - 当 main 字段设置为“main”而不是“browser”时,在 Electron 应用程序中访问 firestore 会导致 INTERNAL UNHANDLED ERROR