Некоторое время назад я столкнулся с той же проблемой и нашел для меня довольно хорошее решение. Я разделяю асинхронные вызовы на другую услугу через wcf таким образом (см. Мой код ниже), делая две вещи для отмены после максимального времени:
Вы можете использовать CancellationToken в сочетании со второй задачей, выполняемой параллельно выполняемой задаче и отменить его, если это необходимо:
private const int TimeOut = 50000;
public static async Task<T> HandleServiceCall<T>(Func<Task<T>> doServiceCall, CancellationTokenSource source) where T : class
{
var delaySource = new CancellationTokenSource(TimeSpan.FromSeconds(50));
source.Token.ThrowIfCancellationRequested();
var res = doServiceCall();
if (await Task.WhenAny(res, Task.Delay(TimeSpan.FromMilliseconds(TimeOut), delaySource.Token)) == res)
{
delaySource.Cancel();
await res;
}
else
{
source.Cancel();
throw new Exception("Your Text");
}
return await res;
}
Вы можете вызвать этот метод для примера следующим образом:
var source = new CancellationTokenSource(TimeSpan.FromSeconds(50));
source.Token.ThrowIfCancellationRequested();
MyWrapperClass.HandleServiceCall(async() => await MyAsyncMethod(source.Token), source).Result
для того, чтобы уточнить, что делается здесь: Я создаю отмену токен для моей задачи с заданной max TimeSpan а затем передать этот токен асинхронному методу, который должен быть вызван. Этот вызов задается как func в моем методе HandleServiceCall. Этот метод создаст еще один CancellationToken с заданным большим TimeSpan, который будет запускаться в качестве отложенной задачи (task.Delay будет просто ждать, пока токен не будет запущен). Task.WhenAny будет выглядеть, если обычная задача асинхронизации или задание с задержкой заканчивается первым. Если это задержка, ваше максимальное время истекло, и генерируется исключение.
Привет Константин
Вы помечено вопрос с 'CancellationTokenSource' - так передать CancellationToken в функцию, и на каждой итерации цикла проверьте его, чтобы узнать, запрошено ли отмена, т. е. 'while (! cancelationToken.IsCancellationRequested) {...' – stuartd