简体   繁体   English

C#取消执行包含多个任务的任务

[英]C# Cancel execution of a task with multiple tasks in it

I'd like to cancel a task that has multiple tasks in it, for example: 我想取消一个包含多个任务的任务,例如:

 private async Task<bool> myTask0() {
       var val2 = await myTask2();
       var val3 = await myTask3();            
       return true;
    }

where: 哪里:

private async Task<bool> myTask1() {
       //run some tasks in paralell
        var myParallel= arrayValues.Select(fileBEanListItem => manageSrcFilesDownload().ToList();
        return true;
    }

   private async Task<bool> myTask2() {
        return await myTask3();
    }

So I'd like to gave the option to cancel myTask0 with all tasks in it - just abort it! 因此,我想选择取消所有任务的myTask0放弃它! Is there a solution: 是否有解决方案:

I am trying: 我在尝试:

 var ts = new CancellationTokenSource();
 CancellationToken ct = ts.Token;

 await Task.Factory.StartNew(async () => {
                await myTask0();
        },ct);

and when I need to close it, I use ts.Cancel(true); 当我需要关闭它时,我使用ts.Cancel(true); but no effect, tasks are running anyway. 但没有效果,无论如何任务仍在运行。

Cancellation is cooperative . 取消是合作的 So, you should pass the CancellationToken down through your methods: 因此,您应该通过方法向下传递CancellationToken

private async Task<bool> myTask0(CancellationToken token) {
   var val2 = await myTask2(token);
   var val3 = await myTask3(token);            
   return true;
}

private async Task<bool> myTask1(CancellationToken token) {
   //run some tasks in paralell
   var myParallel= arrayValues.Select(fileBEanListItem => manageSrcFilesDownload(token).ToList();
   return true;
}

private async Task<bool> myTask2(CancellationToken token) {
    return await myTask3(token);
}

And so on, until you either pass the token to APIs that can take it (eg, file download), or until you have your own code that uses CancellationToken.ThrowIfCancellationRequested or CancellationToken.Register to respond to cancellation. 依此类推,直到您将令牌传递给可以接收令牌的API(例如文件下载),或者直到您拥有使用CancellationToken.ThrowIfCancellationRequestedCancellationToken.Register来响应取消的代码。

On a side note, StartNew is an anti-pattern . 另外, StartNew是反模式 As I explain on my blog, you should use Task.Run instead. 正如我在博客上解释的那样,您应该改用Task.Run In particular, the CancellationToken parameter (for both StartNew and Run ) only cancels the scheduling of the delegate ; 特别是, CancellationToken参数(对于StartNewRun )仅取消委托的调度 they won't abort your code. 他们不会中止您的代码。 For proper cancellation support, you have to write code that responds to a CancellationToken . 为了获得适当的取消支持,您必须编写响应CancellationToken代码。

In addition to Stephen Cleary 除了史蒂芬·克莱里

MSDN states: MSDN指出:

In the Task classes, cancellation involves cooperation between the user delegate, which represents a cancelable operation and the code that requested the cancellation. 在Task类中,取消涉及代表可取消操作的用户委托与请求取消的代码之间的合作。 A successful cancellation involves the requesting code calling the CancellationTokenSource.Cancel method, and the user delegate terminating the operation in a timely manner. 成功的取消涉及请求代码调用CancellationTokenSource.Cancel方法,并且用户委托及时终止操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM