HttpClient загрузка зависла, если соединение падает - PullRequest
0 голосов
/ 26 февраля 2020

Я использую HttpClient для загрузки файлов в приложении C# (. NET Framework 4.6.1).

Проблема с кодом ниже состоит в том, что если соединение падает во время загрузки кода застрял в методе CopyToAsyn c.

У меня та же проблема, если я использую методы WebClient.DownloadFileAsyn c, но вместо этого я хотел бы использовать 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;
        }
    }
}

1 Ответ

0 голосов
/ 27 февраля 2020

Вы должны установить свойство ReadTimeout для Stream, которое вы получаете от HttpClient. ReadTimeout по умолчанию установлено на 300_000 (5 минут).

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.

...