任务取消最佳做法

时间:2011-11-16 15:38:50

标签: c# .net task task-parallel-library

让我们说我有一个处理器,他的工作就是将文件保存回磁盘。这是以Task运行,同时观察BlockingCollection<T>要处理的文件。

当任务被取消并且仍有文件需要保存到磁盘时,这样做有什么好处呢?

在退出之前让任务正确快速将剩余的文件写回磁盘是很方便的,尽管我不确定这是否与取消任务的理念相冲突(因为取消应该尽快发生)。

另一个选择是在取消任务后将第二个过程用于将剩余文件写入磁盘。

代码示例:

class FileProcessor
{
    private readonly BlockingCollection<Stream> input;

    public FileProcessor(BlockingCollection<Stream> input)
    {
        _input = input;
    }

    public Task Run(CancellationToken cancellationToken, 
        BlockingCollection<Stream> input)
    {
        return Task.Factory.StartNew(() => 
        {
            foreach (Stream stream in 
                        input.GetConsumingEnumerable(cancellationToken))
            {
                WriteToDisk(stream);
            }

            // Should I call WriteRemaining here or should I have
                    // a process running after this task exited which 
                    // will call WriteRemaining
            WriteRemaining();
        });
    }

    public void WriteRemaining()
    {
        foreach (Stream stream in input)    
        {
            WriteToDisk(stream);
        }
    }
}

我知道这是一个悬而未决的问题,要编写的应用程序/要求/文件数量也起到了作用,但我在这里寻求一般指南/最佳实践。

1 个答案:

答案 0 :(得分:9)

Cancellation is a cooperative action使用任务并行库时,是的,建议取消是一种快速操作。

请记住,这是取消,而不是取消和清理。如果您因取消而需要执行额外的操作,那么这些操作应该在已取消的原始任务之外进行

请注意,这不会阻止您调用ContinueWith并在 new Task中执行操作,该操作会检查IsCanceled property是否返回{ {1}}然后根据它执行清理。

这里的关键点是你不想阻止被取消的原始true,但你可以自由地开始一个新的Task来执行你需要做的任何清理工作。取消的结果。