当调用的方法没有 return 时取消整个任务
Cancelling an entire task when a called method does not return
我有一个注册后台任务的方法,如下所示:
//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() 方法不会 return 任何东西。这可能是某种 Windows 错误; Register() 方法永远不会在内部完成。事实上,在 10 秒后,调用了 token.ThrowIfCancellationRequested() 方法,但它不会抛出调用它的 try-catch 语句。最初我在没有 Task.Run() 的情况下直接调用 builder.Register() 但它没有用,这个也没有。
但是,如果我将 btr = Task.Run(() =>...
替换为 Task.Delay(ms)
,在 ms > 10000
处,我的预期效果就会发生。
我是不是做错了什么?或者有更好的方法吗?基本上,我只需要在 builder.Register() 几秒钟后未完成时使 registerTask() 方法 return 为 null 的代码。
用类似这样的代码替换代码对我有用:
btr = null;
cancellationTokenSource.CancelAfter(10000);
Task registerTask = Task.Factory.StartNew(() =>
{
btr = builder.Register();
});
Task cancellationTask = Task.Factory.StartNew(() =>
{
while (true)
{
if (cancellationTokenSource.Token.IsCancellationRequested) break;
}
}, cancellationTokenSource.Token);
Task[] tasks = new Task[2] { cancellationTask, registerTask };
Task.WaitAny(tasks);
获取取消请求将触发其中一个任务结束,而不是处理错误,当它结束时我 return 任务注册变量,无论它是否为 null。
我有一个注册后台任务的方法,如下所示:
//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() 方法不会 return 任何东西。这可能是某种 Windows 错误; Register() 方法永远不会在内部完成。事实上,在 10 秒后,调用了 token.ThrowIfCancellationRequested() 方法,但它不会抛出调用它的 try-catch 语句。最初我在没有 Task.Run() 的情况下直接调用 builder.Register() 但它没有用,这个也没有。
但是,如果我将 btr = Task.Run(() =>...
替换为 Task.Delay(ms)
,在 ms > 10000
处,我的预期效果就会发生。
我是不是做错了什么?或者有更好的方法吗?基本上,我只需要在 builder.Register() 几秒钟后未完成时使 registerTask() 方法 return 为 null 的代码。
用类似这样的代码替换代码对我有用:
btr = null;
cancellationTokenSource.CancelAfter(10000);
Task registerTask = Task.Factory.StartNew(() =>
{
btr = builder.Register();
});
Task cancellationTask = Task.Factory.StartNew(() =>
{
while (true)
{
if (cancellationTokenSource.Token.IsCancellationRequested) break;
}
}, cancellationTokenSource.Token);
Task[] tasks = new Task[2] { cancellationTask, registerTask };
Task.WaitAny(tasks);
获取取消请求将触发其中一个任务结束,而不是处理错误,当它结束时我 return 任务注册变量,无论它是否为 null。