Лучшие практики отмены задач - PullRequest
8 голосов
/ 16 ноября 2011

Допустим, у меня есть процессор, задачей которого является сохранение файлов на диске. Это работает как 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 Ответ

9 голосов
/ 16 ноября 2011

Отмена - это совместное действие при работе с библиотекой параллельных задач, и да, отмена рекомендуется выполнять быстро.

Помните, что это отмена , а не отмена и очистка .Если у вас есть дополнительные операции, которые необходимо выполнить в результате отмены, эти операции должны произойти вне исходной задачи , которая была отменена.

Обратите внимание, что это не останавливаетВы звоните ContinueWith и выполняете операцию в новом Task, который проверяет, является ли свойство IsCanceled возвращает true и затем выполняет очистку на основе этого.

Ключевым моментом здесь является то, что вы не хотите блокировать исходный Task, который был отменен, но вы можете запустить новый Task чтобы выполнить необходимую очистку в результате отмены.

...