我有一个耗时的任务,我需要在一个单独的线程中运行,以避免锁定gui线程。随着此任务的进行,它将更新特定的gui控件。
问题是,用户可能会在任务结束之前移动到gui的另一部分,在这种情况下,我必须:
取消正在进行的任务(如果它处于活动状态)
等待取消完成:这很关键,因为耗时的任务的目标是更新特定控件。如果不止一个线程同时尝试这样做,事情可能会变得一团糟。
从头开始执行任务
对于一个具体的例子,假设表单有两个部分:一个是在目录树中导航,另一个是在其中显示缩略图。当用户导航到另一个目录时,需要刷新缩略图。
首先,我想用一个BackgroundWorker和一个AutoResetEvent来等待取消,但我一定弄糟了一些东西,因为我在取消时被锁死了。然后我读到了tpl,它应该取代bgw和更原始的机制。
使用第三方物流能很容易做到这一点吗?

最佳答案

有几点需要注意:
你可以从CancellationToken获得CancellationTokenSource
任务取消是一种协作操作:如果您的任务没有定期检查CancellationToken.IsCancellationRequested属性,那么无论您尝试取消任务多少次,它都会愉快地消失。
上面说,总的来说:

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

08-06 01:22
查看更多