从任务主体内部取消任务
Posted
技术标签:
【中文标题】从任务主体内部取消任务【英文标题】:Task cancellation from inside the task body 【发布时间】:2014-08-16 10:59:44 【问题描述】:我阅读了有关取消方法的信息,但根据我的理解,它们都可以从任务外部控制任务,但如果我想从内部取消任务。
例如在这个伪代码中:
Task tasks = new Task(() =>
bool exists = CheckFromDB();
if (!exists)
break;
我可以从内部取消任务吗? 我得到的唯一想法是在任务内部触发异常并从外部处理它,但这不是正确的方法。
【问题讨论】:
【参考方案1】:如果您想真正取消任务(例如,在完成后将Status
属性设置为Canceled
),您可以这样做:
var cts = new CancellationTokenSource();
var token = cts.Token;
Task innerCancel = new Task(
() =>
if (!CheckFromDB())
cts.Cancel();
token.ThrowIfCancellationRequested();
,
token);
当您使用return
时,任务实际上不会取消,而是不会执行return
语句之后的代码,并且任务本身的状态为@987654328 @。
在旁注中,advised 使用 Task.Factory.StartNew
用于 .NET 4,Task.Run
用于 .NET 4.5 而不是构造函数来创建任务。
【讨论】:
这是一种更好的方法。 你应该使用Task.Run
而不是new Task
来返回一个热任务而不是一个冷任务
@YuvalItzchakov,我同意使用Task.Run
而不是返回一个冷任务,但在这种情况下,为了保持一致性,我决定遵循 OP 编写它的方式。
我认为你应该向 OP 展示正确的路径,而不是坚持不正确的一致性:)
请注意,如果您不需要在任务之外取消,您也可以删除取消令牌并使用throw new OperationCanceledException()
代替cts.Cancel()
以获得类似的效果。【参考方案2】:
任务中的 lambda 表达式代码的行为与任何其他方法中的行为相同。如果你出于某种原因想结束任务,你可以简单地返回:
Task task = Task.Run(() =>
if(!CheckFromDB())
return;
您也可以抛出异常。这将结束任务并将其标记为错误,但如果您可以避免它,则没有理由这样做。如果你真的在回应一些你无法克服的问题,那么是的,只要抛出一个异常。
【讨论】:
没有我可以使用或分配的属性,以便我可以处理退货。 @user733659 想知道具体的退货吗?不是真的......但是你可以让 lambda 返回一个值(可能是一个布尔值)。你也可以抛出一个特定的异常。 您可以使用事件或blogs.msdn.com/b/csharpfaq/archive/2010/07/19/…以上是关于从任务主体内部取消任务的主要内容,如果未能解决你的问题,请参考以下文章
如何从另一个任务中取消 ScheduledFuture 任务并优雅地结束?
上QQ任务栏出现ffdshow audio decoder!怎么取消!
Chocolatey 和 powershell:从任务栏和文件关联中固定和取消固定程序