I have a time consuming task which I need to run in a separate thread to avoid locking the GUI thread. As this task progresses, it updates a specific GUI control.
The catch is that the user might move to another part of the GUI before the task is over, and in that case, I have to:
- Cancel the ongoing task (if it is active)
- Wait till it’s done cancelling: this is crucial, because the time consuming task’s objective is to update a specific control. If more than one thread tries to do it at once, things might get messy.
- Launch the task from scratch
For a concrete example, imagine the form has two parts: one where you navigate a directory tree, and another where you display thumbnails. When the user navigates to another directory, thumbnails need to be refreshed.
First I thought of using a BackgroundWorker and an AutoResetEvent to wait for cancellation, but I must have messed something because I got deadlocked when cancelling. Then I read about TPL, which is supposed to replace BGW and more primitive mechanisms.
Can this be done easily using TPL?
A few things to note:
You can get a
CancellationTokenfrom aCancellationTokenSourceTask cancellation is a cooperative action: if your task does not periodically check the
CancellationToken.IsCancellationRequestedproperty, it doesn’t matter how many times you try to cancel the task, it will merrily churn away.Those things said, here’s the general idea: