У меня есть следующее расширение, которое позволяет мне заставить тайм-аут выполнять задачу.Расписание задач при вызове внешнего метода
public static async Task<T> TimeoutAfter<T>(this Task<T> task, TimeSpan timeSpan, string message = null)
{
if (task == await Task.WhenAny(task, Task.Delay(timeSpan)))
return await task;
else
{
throw new TimeoutException(message);
}
}
У меня есть следующая задача:
private async Task<string> TestTask(PageData page)
{
await Task.Delay(TimeSpan.FromSeconds(10));
return "teststring";
}
Когда я называю задачу, используя следующий я получаю желаемый результат.
var teststring = await TestTask()
.TimeoutAfter(TimeSpan.FromSeconds(5), "timeout message");
я выдаю я имею что когда я вызываю метод во внешней библиотеке (в данном случае с ++ CLR библиотеки классов), код внутри TimeoutAfter() никогда не будет достигнуто, и задача никогда не таймаута. Я могу исправить проблему, используя Task.Factory.StartNew() (см. Ниже), передав обратный вызов долговременной задаче и создав задачу Task.Delay перед запуском основной задачи, но это не будет работать как расширение ,
private async Task<T> Timeout<T>(Func<Task<T>> taskFunc)
{
var taskWait = Task.Delay(TimeSpan.FromSeconds(15));
var task = Task.Factory.StartNew(() => taskFunc());
if (task == await Task.WhenAny(task, taskWait))
return await (await task);
else
{
throw new TimeoutException("timeout");
}
}
Почему кажется, что код в TimeoutAfter() только выполнение, когда определенное содержание в задаче она простирающаяся? Какую функциональность можно добавить к расширению, чтобы это не происходило?
Вы делаете это в Windows Forms или WPF UI, случайно? Можете ли вы создать короткую, но полную программу, демонстрирующую проблему? Это не помогает, что мы ничего не знаем о методе, который вы вызываете, асинхронно? # –
Вы должны знать, что это не «тайм-аут» в традиционном смысле. Ваша задача не прервана, только время ожидания. Задача будет продолжаться, и если это бесконечный цикл или какая-то другая долго работающая задача, у нее могут быть очень странные побочные эффекты. Вероятно, вы также не будете знать, будут ли исключения выбраны в этой задаче после таймаута. –
@JonSkeet Выполняется код в консольном приложении, метод, вызываемый в задаче, вызывает метод в библиотеке классов CLR CLR, который, в свою очередь, вызывает внешние DLL, связанные с библиотекой изображений. Существуют ли определенные условия, при которых задача будет выполняться синхронно, а расширение не будет вызвано? – jimmyjambles