首页 > 解决方案 > 如果连接断开,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;
        }
    }
}

标签: c#.netdownloaddotnet-httpclient

解决方案


您必须设置ReadTimeout从. 默认设置为(5 分钟)。StreamHttpClientReadTimeout300_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 上返回。


推荐阅读