Поэтому я создал обработчик задач. Я хочу, чтобы он работал в течение некоторого заранее определенного гарантированного периода времени, затем я хочу сделать некоторые из своих вещей, и только тогда мне нужно, чтобы результат обработчика ожидался. Что-то вроде:
var th = TaskCreator();
th.awaitFor(5000);
//do some work
var result = await th;
Итак, как асинхронная задача может выполняться в течение заданного количества секунд?
Вы можете использовать WhenAny (документы):
var th = TaskCreator();
await Task.WhenAny(Task.Delay(TimeSpan.FromSeconds(5)), th);
//do some work
var result = await th;
Это прекратит ожидание завершения любой из задач, а это означает, что вы можете затем выполнить свою другую работу и переждать th в конце, чтобы дождаться ее завершения (или просто получить результат, если он уже завершен).
Если ваш метод TaskCreator выполняет много синхронной работы, прежде чем перейти к асинхронному, вы можете сначала вызвать await Task.Yield(); (docs) внутри метода TaskCreator, прежде чем использовать приведенный выше код.
Это, вероятно, даст вам предупреждение на .NET 8.
Предпочтительным механизмом здесь было бы реализовать отмену в вашем TaskCreator. Это дает множество преимуществ:
TaskCreator
фактически прекратить работу, когда истек тайм-аутПример:
using var cs = new CancellationTokenSource();
cs.CancelAfter(TimeSpan.FromSeconds(5));
var result = await TaskCreator(cs.Token);
Где ваш TaskCreator предположительно будет выглядеть примерно так:
async Task<int> TaskCreator(CancellationToken cancellationToken)
И где вы на самом деле используете cancellationToken в TaskCreator, либо напрямую (обычно через .ThrowIfCancellationRequested() или .Register(...)), либо косвенно (передавая его нижестоящим ожидаемым API).
Ответ Марка идеален. Если вы не можете добавить отмену по какой-либо причине, вы можете использовать WaitAsync:
var th = TaskCreator();
var result = await th.WaitAsync(TimeSpan.FromSeconds(5));
WaitAsync похож на обычный WhenAny подход, но без утечки таймеров.
Обратите внимание, что и WaitAsync, и WhenAny не отменяют операцию; они просто отменяют (а) ожидание. Ответ Марка правильно отменит операцию.
Не совсем очевидно, что в случае, если timeout истекает до завершения задачи, Task.WaitAsync распространяет TimeoutException.
Что такое var th? Это Task? Пожалуйста, напишите конкретные типы на StackOverflow. Мы не можем навести указатель мыши на var и увидеть тип переменной!