Task cancellation best practices

余生颓废 提交于 2020-12-05 05:32:22

问题


Lets say I have a processor who's job is to persist files back to the disk. This is running as a Task while observing a BlockingCollection<T> for files to process.

When the task gets cancelled and there are still files which should be saved to the disk, what would be a good practice for doing so?

It would be convenient to let the task right before exiting quickly write the files remaining back to the disk although I'm not sure if this conflicts with the philosophy of cancelling a task (since cancellation should happen as quick as possible).

Another option is having a second procedure after cancelling the task who's job is to write the remaining files to the disk.

Code example:

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

I know this is a bit of an open question, the application/requirements/amount of files to write also play a role but I'm seeking for the general guideline/best practices here.


回答1:


Cancellation is a cooperative action when working with the Task Parallel Library, and yes, cancelling is recommended to be a quick operation.

Remember, this is a cancellation, not a cancellation and cleanup. If you have extra operations that you need to perform as the result of a cancellation, then those operations should occur outside of the original task that was cancelled.

Note that this doesn't stop you from calling ContinueWith and performing an operation in a new Task which checks to see if the IsCanceled property returns true and then performs the cleanup based on that.

The key point here is that you don't want to block the original Task that was cancelled, but you are free to start a new Task to perform whatever cleanup you need to do as a result of the cancellation.



来源:https://stackoverflow.com/questions/8154318/task-cancellation-best-practices

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!