Я загружаю много маленьких файлов (размером около 1 МБ) в цикле, и я хочу, чтобы этот цикл прервался в случае потери интернет-соединения. Но httpClient.GetAsync
зависает и не исключение, если я выключаю Wi-Fi (или вынимаю шнур) во время его работы. Также он не отменяется, если я использую CancelationToken (если он отменен до httpClient.GetAsync
, он отменяется, но мне нужно отменить его во время выполнения).
Мой опыт показывает, что если интернет исчезнет до вызова httpClient.GetAsync(url, cancellationToken);
, он выдаст исключительную ситуацию, но если интернет исчезнет, httpClient.GetAsync(url, cancellationToken);
уже начнет работать, то он будет зависать бесконечно, и даже если я вызову, установите CancelationTokenSource.Cancel()
, операция не будет отменена.
Функция с использованием HttpClient
private static readonly HttpClient httpClient = new HttpClient();
protected async Task<byte[]> HttpGetData(string url, CancellationToken cancellationToken)
{
var response = await httpClient.GetAsync(url, cancellationToken);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsByteArrayAsync();
}
вызывается из цикла с использованием строки
byte[] data = await LimitedTimeAwaiter<byte[]>.Execute(
async (c) => { return await HttpGetData(chunkUrl, c); }, cancellationToken, 5);
пока здесь код LimitedTimeAwaiter
public class LimitedTimeAwaiter<T>
{
public static async Task<T> Execute(Func<CancellationToken, Task<T>> function, CancellationToken originalToken, int awaitTime)
{
originalToken.ThrowIfCancellationRequested();
CancellationTokenSource timeout = new CancellationTokenSource(TimeSpan.FromSeconds(awaitTime));
try
{
return await function(timeout.Token);
}
catch (OperationCanceledException err)
{
throw new Exception("LimitedTimeAwaiter ended function ahead of time", err);
}
}
}
Хотя я отменяю токен, данный httpClient.GetAsync
, он не генерирует исключение OperationCanceledException и бесконечно зависает. Я ищу способ прервать его, если не возвращает значение в течение ограниченного периода времени.