c# - 任务取消最佳实践

标签 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);
        }
    }
}

我知道这是一个悬而未决的问题,应用程序/要求/要写入的文件数量也有影响,但我正在寻找一般准则/最佳实践。

最佳答案

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

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

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

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

关于c# - 任务取消最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8154318/

相关文章:

c# - 如何将 UTC+0 日期转换为 PST 日期?

.net - WM_CLOSE 和 SC_CLOSE 之间的区别

.NET - 启用 UAC (Windows7/Vista) 时,应用程序如何能够 self 更新?

c# - 任务同步的正确方法?

c# - 在 C# 中,为什么 "int"是 System.Int32 的别名?

c# - Restful 网址。查看特定型号

c# - 验证错误的正确返回类型

c# - 如何在 wpf 中单击 Panel.ZIndex 低于另一个的对象?

visual-studio-code - 每个用户在Visual Studio Code中创建任务

c# - 在 C# 中,如何让一组任务完成后运行一个任务?