Шаблон тайм-аута для асинхронного метода на основе задач в C #
Насколько я знаю, есть два возможных шаблона для реализации тайм-аута для асинхронных методов на основе задач:
Встроенный тайм-аутpublic Task DoStuffAsync(TimeSpan timeout)
Этот подход сложнее реализовать, потому что это нелегко реализоватьГлобальный тайм-аут для всего стека вызовов. Например, контроллер веб-API получает запрос HTTP и вызываетDoStuffAsync
и абонент хочет глобальное время ожидания 3 секунды.
То есть каждый внутренний вызов асинхронного метода должен получать вычитание уже использованного времени ...
Нет встроенного тайм-аутаpublic Task DoStuffAsync(CancellationToken cancellationToken)
..........
CancellationTokenSource cancellationSource = new CancellationTokenSource();
Task timeoutTask = Task.Delay(3000);
if(await Task.WhenAny(DoStuffAsync(cancellationTokenSource), timeoutTask) == timeoutTask)
{
cancellationSource.Cancel();
throw new TimeoutException();
}
Кажется, это наиболее надежный и простой в реализации шаблон. Первый абонент определяет глобальное время ожидания, и если онотайм-аутывсе ожидающие операции будут отменены. Кроме того, он предоставляет токен отмены непосредственному абоненту, и внутренние вызовы будут использовать одну и ту же ссылку на токен отмены. Таким образом, если тайм-аут верхнего абонента, он сможет отменить любой рабочий поток.
Весь вопросЕсть ли какой-то шаблон, который я пропускаю, или, я правильно, если я разрабатываю API, используянет встроенного тайм-аута?