问题
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