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:
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?
It works fine when have one or two tasks however throws an error "A task was cancelled" when we have more than one task listed. List<Task> allTasks = new List<Task>(); allTasks.Add(....
CancellationTokenSource – an object responsible for creating a cancellation token and sending a cancellation request to all copies of that token. CancellationToken – a structure used by listeners to monitor token current state.
A CancellationToken enables cooperative cancellation between threads, thread pool work items, or Task objects. You create a cancellation token by instantiating a CancellationTokenSource object, which manages cancellation tokens retrieved from its CancellationTokenSource.
A few things to note:
You can get a CancellationToken
from a CancellationTokenSource
Task cancellation is a cooperative action: if your task does not periodically check the CancellationToken.IsCancellationRequested
property, 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:
void Main()
{
var tokenSource = new CancellationTokenSource();
var myTask = Task.Factory
.StartNew(() => DoWork(tokenSource.Token), tokenSource.Token);
Thread.Sleep(1000);
// ok, let's cancel it (well, let's "request it be cancelled")
tokenSource.Cancel();
// wait for the task to "finish"
myTask.Wait();
}
public void DoWork(CancellationToken token)
{
while(!token.IsCancellationRequested)
{
// Do useful stuff here
Console.WriteLine("Working!");
Thread.Sleep(100);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With