c# - 取消任务并等待它完成

标签 c# task-parallel-library

我有一项耗时的任务,我需要在单独的线程中运行以避免锁定 GUI 线程。随着此任务的进行,它会更新特定的 GUI 控件。

问题是用户可能会在任务结束前移动到 GUI 的另一部分,在这种情况下,我必须:

  1. 取消正在进行的任务(如果它处于事件状态)
  2. 等到它完成取消:这很重要,因为耗时任务的目标是更新特定控件。如果有多个线程同时尝试执行此操作,事情可能会变得一团糟。
  3. 从头开始任务

举一个具体的例子,假设表单有两部分:一部分用于导航目录树,另一部分用于显示缩略图。当用户导航到另一个目录时,需要刷新缩略图。

首先我想到了使用 BackgroundWorkerAutoResetEvent 来等待取消,但我一定是搞砸了,因为我在取消时陷入了僵局。然后我读到了 TPL,它应该取代 BGW 和更原始的机制。

这可以使用 TPL 轻松完成吗?

最佳答案

一些注意事项:

  • 您可以从CancellationTokenSource

  • 获取CancellationToken
  • 任务取消是一种协作操作:如果您的任务不定期检查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);
    }
}

关于c# - 取消任务并等待它完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14882123/

相关文章:

c# - 比手动字典更好的选项来引用其中正在运行的方法的 'current task'?

c# - Parallel.ForEach仅在未运行代码时才在启动时执行两次吗?

c# - 两个更新面板

c# - 如何将同一个项目中的类编译到不同的DLL

c# - C++ .NET DLL 与 C# 托管代码? (文件加密 AES-128+XTS)

c# - 如何排队/等待 TPL 任务完成

c# - Parallel.For与ThreadPool和异步/等待

.net - TPL数据流和Akka.net有什么区别?

c# - Azure BlobWriteStream 客户端无法在指定超时内完成操作

c# - IDX20803 : Unable to obtain configuration from: 'https://localhost/IdentityServer/Core/.well-known/openid-configuration'