Re: CancellationTokenSource неудобный какой-то
От: RushDevion Россия  
Дата: 28.06.22 10:29
Оценка: 8 (2)
Ну да, примерно так.
Только еще обработку ошибок нужно сделать, иначе на первом hub timeout упадет.

Можно упростить как-нибудь вот так:
// Добавляем Extension
public static async Task<TResult> WithTimeout<TResult>(this Task<TResult> task, TimeSpan timeout, CancellationToken cToken)
{
    using var cts = CancellationTokenSource.CreateLinkedTokenSource(cToken);
    var completedTask = await Task.WhenAny(task, Task.Delay(timeout, cts.Token));
    if (completedTask == task)
    {
        cts.Cancel();   // Cancel to stop timer
        return await task;
    }
    else
    {
        throw new TimeoutException();
    }
}

// И будет покрасивше
public Task LocatePackageAsync(string name, CancellationToken cToken) => LocatePackageCoreAsync(name, cToken).WithTimeout(TimeSpan.FromSeconds(30));

public async Task LocatePackageCoreAsync(CancellationToken cToken)
{
    foreach (var hub in hubs)
    {
        try
        {
            var hub = await ConnectAsync(hub).WithTimeout(TimeSpan.FromSeconds(5), cToken);
            var package = await hub.LocatePackage(package).WithTimeout(TimeSpan.FromSeconds(5), cToken);
            if (package != null) return package;
        }
        catch (TimeoutException) { /* Ignore hub operation timeout */ }
    }

}
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.