gpt4 book ai didi

c# - 取消TPL数据流 block 的正确方法

转载 作者:行者123 更新时间:2023-12-03 16:48:52 30 4
gpt4 key购买 nike

我正在使用 TPL阻止执行用户可能取消的操作:
我想出了两个选项,首先我取消整个块但不取消块内的操作,如下所示:

_downloadCts = new CancellationTokenSource();

var processBlockV1 = new TransformBlock<int, List<int>>(construct =>
{
List<int> properties = GetPropertiesMethod(construct );
var entities = properties
.AsParallel()
.Select(DoSometheningWithData)
.ToList();
return entities;
}, new ExecutionDataflowBlockOptions() { CancellationToken = _downloadCts.Token });

第二个我取消内部操作,但不是块本身:
var processBlockV2 = new TransformBlock<int, List<int>>(construct =>
{
List<int> properties = GetPropertiesMethod(construct);
var entities = properties
.AsParallel().WithCancellation(_downloadCts.Token)
.Select(DoSometheningWithData)
.ToList();
return entities;
});

据我了解,第一个选项将取消整个块,从而关闭整个管道。我的问题是它是否也会取消内部操作并处理所有资源(如果有的话)(打开 StreamReaders 等),或者最好选择第二个选项,然后我自己可以确保所有内容都被取消和清理,然后我可以使用一些手段(铁路编程) float 升高 OperationCanceledException顺流而下,在我想要的地方处理它?

最佳答案

这两个选项并不等效。

  • 第一个选项( CancellationToken = _downloadCts.Token )将使 processBlockV1阻止丢弃当前在其缓冲区中的任何消息(其 InputCount 属性将变为 0 ),并停止接受新消息(调用其 Post 方法将始终返回 false )。它不会停止处理当前正在进行的消息。这些将被完全处理,但不会传播到任何链接块。处理完这些消息后,块将在取消状态下完成(其 Completion .Status 属性将变为 Canceled )。
  • 第二个选项(取消内部操作)对整个块没有影响。 Dataflow 块可容忍任何 OperationCanceledException 从他们的处理函数中抛出,并忽略有问题的项目并继续下一个。所以在 token 取消后,所有发布的消息仍然会被处理,并且该块将继续接受更多。它只是不会向其链接的块传播任何内容,因为所有项目都会抛出 OperationCanceledException并被忽略。在具体示例中,GetPropertiesMethod方法将被所有 construct 调用消息,因此会延迟块的完成。区块的最终状态将是 RanToCompletion .

  • 重要的是要知道 Dataflow 块正在认真对待 Completion 的概念。 .在报告完成之前,他们将等待他们知道的一切停止运行。如果您确实希望它们过早完成并留下仍在运行的任务,您将不得不使用 wrapping your tasks with cancelable wrappers 之类的技巧。 .

    关于c# - 取消TPL数据流 block 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62080674/

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