У меня есть метод, который регистрирует фоновую задачу, которая выглядит следующим образом:Отменять всю задачу, когда вызываемый метод не возвращает
//snippet from task builder method
try
{
cancellationTokenSource.CancelAfter(10000);
btr = Task.Run(() => registerTask(builder, btr,cancellationTokenSource.Token), cancellationTokenSource.Token).Result;
}
catch (OperationCanceledException) // something went wrong
{
return null;
}
private BackgroundTaskRegistration registerTask(BackgroundTaskBuilder builder, BackgroundTaskRegistration btr, CancellationToken token)
{
CancellationTokenSource newToken = new CancellationTokenSource();
Task cancelledCheck = Task.Run(() =>
{
while (true)
{
if (token.IsCancellationRequested)
{
newToken.Cancel();
token.ThrowIfCancellationRequested();
}
}
}, newToken.Token);
btr = Task.Run(()=> builder.Register(),token).Result;
return btr;
}
Моя проблема заключается в том, что иногда метод builder.Register() не возвращает что-нибудь. Вероятно, это ошибка Windows; метод Register() никогда не заканчивается внутренне. Действительно, через 10 секунд вызывается метод token.ThrowIfCancellationRequested(), но он не бросает в оператор try-catch, где он вызывается. Первоначально я вызывал builder.Register() непосредственно без Task.Run(), но это не сработало, и это тоже не так.
Однако, если я заменил btr = Task.Run(() =>...
на Task.Delay(ms)
, где ms > 10000
, мой предполагаемый эффект произойдет.
Я что-то не так? Или есть лучший способ сделать это? В основном мне нужен только код, который сделает метод registerTask() возвратом null в builder.Register() не завершится через несколько секунд.
Использование '.Result' проблематично, так как это заблокирует поток; вы можете использовать асинхронные функции и «ждать»? – Jacob
@Jacob Возможно, это то, что происходит? Я делаю это из проекта Windows Runtime, поэтому я не могу выполнить свою задачу async, моя ошибка компиляции говорит о том, что я должен изменить тип «Задача» на IAsyncAction или что-то еще, но я еще этого не сделал – Tyress