Ну да, примерно так.
Только еще обработку ошибок нужно сделать, иначе на первом 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 */ }
}
}
}