gpt4 book ai didi

c# - 使用 ContinueWith 时如何捕获 OperationCanceledException

转载 作者:太空狗 更新时间:2023-10-29 22:36:51 25 4
gpt4 key购买 nike

我有一些代码要从 .NET 4.5 的可爱 asyncawait 关键字降级到 .NET 4.0。我正在使用 ContinueWith 创建一个类似于 await 工作方式的延续。

基本上,我的旧代码是:

var tokenSource = newCancellationTokenSource();
var myTask = Task.Run(() =>
{
return MyStaticClass.DoStuff(tokenSource.Token);
}, tokenSource.Token);
try
{
var result = await myTask;
DoStuffWith(result);
}
catch (OperationCanceledException)
{
// Cancel gracefully.
}

(正如人们所料,MyStaticClass.DoStuff(token) 定期调用 token.ThrowIfCancellationRequested()。)

我的新代码如下所示:

var tokenSource = new CancellationTokenSource();
try
{
Task.Factory.StartNew(() =>
{
return MyStaticClass.DoStuff(tokenSource.Token);
}, tokenSource.Token)
.ContinueWith(task =>
{
var param = new object[1];
param[0] = task.Result;
// I need to use Invoke here because "DoStuffWith()" does UI stuff.
Invoke(new MyDelegate(DoStuffWith, param));
});
}
catch (OperationCanceledException)
{
// Cancel gracefully.
}

但是,从未捕获到 OperationCanceledException。这是怎么回事?我应该把 try/catch block 放在哪里?

最佳答案

取消的处理方式与其他异常不同。基本上,您可以使用这种模式:

Task.Factory.StartNew(() =>
{
// The task
}, tokenSource.Token)
.ContinueWith(task =>
{
// The normal stuff
}, TaskContinuationOptions.OnlyOnRanToCompletion)
.ContinueWith(task =>
{
// Handle cancellation
}, TaskContinuationOptions.OnlyOnCanceled)
.ContinueWith(task =>
{
// Handle other exceptions
}, TaskContinuationOptions.OnlyOnFaulted);

或者另一种:

Task.Factory.StartNew(() =>
{
// The task
}, tokenSource.Token)
.ContinueWith(task =>
{
switch (task.Status)
{
case TaskStatus.RanToCompletion:
// The normal stuff
break;
case TaskStatus.Canceled:
// Handle cancellation
break;
case TaskStatus.Faulted:
// Handle other exceptions
break;
}
});

在你的例子中,你没有捕捉到任何东西,因为:

  • Task.Factory.StartNew 立即返回并始终成功。
  • 您的延续始终运行
  • 正在访问 task.Result抛出 AggregateException 因为任务被取消
  • 异常未被任何处理,因为它是从线程池线程中抛出的。哎呀。接下来会发生什么 depends on the framework version :

    • 在 .NET < 4.5 中,一旦失败的任务完成,进程将终止,因为您有未观察到的异常。
    • 在 .NET >= 4.5 中,异常将被静默删除。

关于c# - 使用 ContinueWith 时如何捕获 OperationCanceledException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30248572/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com