简体   繁体   中英

Cancel task and wait for it to finish

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:

  1. Cancel the ongoing task (if it is active)
  2. 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.
  3. 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 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);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM