C# 任务取消,什么时候?

C# 任务取消,什么时候?,c#,.net,task-parallel-library,C#,.net,Task Parallel Library,对于我正在制作的API的实现,我希望用户能够取消他们的任务(Task)。我想我需要一个CancellationTokenSource,这样我就可以从前者创建一个CancellationToken。现在我正在处理取消请求(IsCancellationRequested/throwifccancellationrequested),我有点困惑。检查/执行此操作的适当时间是什么 例如(虚构的): async Task DoStuff(整数,取消令牌){ //1.在这里,被叫方站点? token.Thr

对于我正在制作的API的实现,我希望用户能够取消他们的任务(Task)。我想我需要一个
CancellationTokenSource
,这样我就可以从前者创建一个
CancellationToken
。现在我正在处理取消请求(
IsCancellationRequested
/
throwifccancellationrequested
),我有点困惑。检查/执行此操作的适当时间是什么

例如(虚构的):

async Task DoStuff(整数,取消令牌){
//1.在这里,被叫方站点?
token.ThrowIfCancellationRequested();
var resultTask1=_database.GetSomeDataFromDatabase(token);//2。是否在此方法中?
var resultTask2=_service.SomeRestCall(token);//2。在这个内部?
//3.这里,在任务返回之前?
token.ThrowIfCancellationRequested();
var result1=等待结果task1;
var result2=等待结果task2;
//4.内存处理,在这里?
foreach(result1中的var项)
{
// ...
}
foreach(结果2中的var项)
{
//1.这里?
token.ThrowIfCancellationRequested();
等待_fileSystem.Save(文件名、项、令牌);//5。是否在该文件中?
}
//6.这里可能没有意义,结果已经被检索到了?
返回123;
}

任务取消的最佳实践是什么?

取消通常在等待需要时间的操作时完成。例如,等待IO操作或进行基于CPU的计算

在您的示例中,确实没有必要在1、2和6处取消,因为它们会毫不延迟地快速通过

然而,如果列表很大或计算需要时间,则在#4中检查取消是有意义的

最后#5是赢家,因为IO速度不快。但是,是否
\u fileSystem.Save
抛出
任务取消异常
?那样的话,它已经被处理好了


请注意,通过使用取消令牌,您也可以说事情是可恢复的。如果没有,请在文档中明确说明,取消操作只会中止那些尚未保存的计算。

通常在等待需要时间的操作时执行取消操作。例如,等待IO操作或进行基于CPU的计算

在您的示例中,确实没有必要在1、2和6处取消,因为它们会毫不延迟地快速通过

然而,如果列表很大或计算需要时间,则在#4中检查取消是有意义的

最后#5是赢家,因为IO速度不快。但是,是否
\u fileSystem.Save
抛出
任务取消异常
?那样的话,它已经被处理好了

请注意,通过使用取消令牌,您也可以说事情是可恢复的。如果没有,请在文档中明确说明,取消操作只会中止那些尚未保存的计算。

没有所谓的“最佳实践”。在不同的场景中,it的使用可能会有所不同

基本上,
ThrowIfCancellationRequested()
用于在请求取消时防止运行任何额外的代码行。将其视为以下类型检查:

if (token.IsCancellationRequested) 
    throw new OperationCanceledException(token); // break the processing immediately
现在由您决定在请求取消时哪个代码段应该停止执行。正如@Jgauffin所建议的,长时间运行的代码段将是放置此类检查的好地方。此外,如果在给定的示例2中有多个区域用于循环,则可以在这两个区域中使用,以避免在请求取消时进行进一步处理。

没有所谓的“最佳实践”。在不同的场景中,it的使用可能会有所不同

基本上,
ThrowIfCancellationRequested()
用于在请求取消时防止运行任何额外的代码行。将其视为以下类型检查:

if (token.IsCancellationRequested) 
    throw new OperationCanceledException(token); // break the processing immediately
现在由您决定在请求取消时哪个代码段应该停止执行。正如@Jgauffin所建议的,长时间运行的代码段将是放置此类检查的好地方。此外,如果在给定的示例2中有多个区域用于循环,则可以在这两个区域中使用,以避免在请求取消时进行进一步处理

检查/执行此操作的适当时间是什么

对于CPU限制的方法,应该定期调用
CancellationToken.throwifcancellationrequest
。例如,如果您有一个紧密的处理循环,那么您可能希望每隔几百次左右调用一次

然而,听起来您的情况完全是I/O绑定的(自然是异步的)。在这种情况下,最好只传递令牌。更高级别的异步方法只能传递令牌。在最低级别,如果API不直接支持
CancellationToken
,则通常最好使用
CancellationToken.Register
来实现异步操作的真正取消。当然,如果最低级别的API确实直接支持
CancellationToken
,那么只需传递它即可

检查/执行此操作的适当时间是什么

对于CPU限制的方法,应该定期调用
CancellationToken.throwifcancellationrequest
。例如,如果您有一个紧密的处理循环,那么您可能希望每隔几百次左右调用一次


然而,听起来您的情况完全是I/O绑定的(自然是异步的)。在这种情况下,最好只传递令牌。更高级别的异步方法只能传递令牌。在最低级别,如果API不直接支持
CancellationToken
,则通常最好使用
CancellationToken.Register
来实现异步操作的真正取消。当然,如果最低级别的API确实直接支持
CancellationToken
,那么只需将其传递出去。

我认为如果任务很小,可以将取消检查放入ju