【发布时间】:2013-01-12 09:15:38
【问题描述】:
我的 C# 任务被取消了,但不是我。我没有得到堆栈跟踪,也无法确定问题出在哪里。
我的任务调用如下所示:
var t = Task<Boolean>.Factory.StartNew(() =>
{
Boolean bOk = DoSomthingImportant();
return bOk;
}, TaskCreationOptions.AttachedToParent)
.ContinueWith<Boolean>((theTask) =>
{
var reason = theTask.IsCanceled ? "it was canceled" : "it faulted";
Debug.WriteLine("Error: Task ended because " + reason + ".");
... log the exception to one of my objects...
return false;
}, TaskContinuationOptions.NotOnRanToCompletion);
如果任务出错或被取消,我希望继续任务运行,但如果运行正常则不运行。 延续永远不会执行。
稍后我的程序捕获了一个 AggregateException,它包装了一个 TaskCanceledException。
我与任务的其他主要交互是调用 WaitAny(taskArray, timeout) 直到我没有更多任务要启动,然后调用 WaitAll 直到最后一个任务完成为止。
超时的 WaitAny 会导致取消吗?为什么我的延续没有被调用?
这只是我第二次刷任务库,所以我一无所知。
更新:
我发现了这个 SO 问题:如何将任务的已取消状态传播到继续任务。 上面代码中的一个错误(但不是取消的原因)是我假设继续任务状态与原始任务的状态相同。事实上,正如另一篇文章所述,您必须做一些工作才能从另一个那里得到一个。
更新 2:
Brian:感谢您提供文档参考。我已经在高低搜索了任务被取消的其他原因,但错过了这些词:
"如果您正在等待一个转换为已取消状态的任务, 制造并抛出一个任务(包装在 AggregateException 中)。 请注意,此异常表示成功取消而不是 错误的情况。因此,Task 的 Exception 属性返回 空。”
【问题讨论】:
-
不知道您的问题是什么,但您可能不知道在访问
Task.Factory(在Task上定义)和调用ContinueWith(它将根据您返回的内容进行推断)。当然它对错误没有帮助,只是使语法更短。 -
谢谢你的小费,丹。我喜欢简洁的代码。
标签: c# .net task-parallel-library