任务取消最佳做法

Pol*_*ity 8 .net c# 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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

cas*_*One 9

使用任务并行库时,取消是一种合作操作,是的,建议取消是一种快速操作.

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

请注意,这并不会阻止您调用ContinueWith并在 的操作中执行操作,以Task检查IsCanceled属性是否返回true,然后根据该属性执行清理.

这里的关键点是你不想阻止Task被取消的原件,但你可以自由地启动一个新的Task来执行取消后你需要做的任何清理工作.