在没有CancellationToken的情况下停止任务

Tim*_*Tim 5 c# cancellation async-await

我正在使用具有async方法但不是CancellationToken重载的外部库.

现在我正在使用另一个StackOverflow问题的扩展方法来添加CancellationToken:

    public async static Task HandleCancellation(this Task asyncTask, CancellationToken cancellationToken)
    {
        // Create another task that completes as soon as cancellation is requested. http://stackoverflow.com/a/18672893/1149773
        TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
        cancellationToken.Register(() =>
            tcs.TrySetCanceled(), useSynchronizationContext: false);
        Task cancellationTask = tcs.Task;

        // Create a task that completes when either the async operation completes, or
        // cancellation is requested.
        Task readyTask = await Task.WhenAny(asyncTask, cancellationTask);

        // In case of cancellation, register a continuation to observe any unhandled exceptions
        // from the asynchronous operation (once it completes). In .NET 4.0, unobserved task
        // exceptions would terminate the process.
        if (readyTask == cancellationTask)
            asyncTask.ContinueWith(_ => asyncTask.Exception,
                TaskContinuationOptions.OnlyOnFaulted |
                TaskContinuationOptions.ExecuteSynchronously);

        await readyTask;
    }
Run Code Online (Sandbox Code Playgroud)

但是,基础任务仍然执行完成.这不是什么大问题,但有时候底层任务永远不会完成并消耗99%的CPU.

有没有办法在不杀死进程的情况下"杀死"任务?

Ste*_*ary 8

我正在使用另一个StackOverflow问题的扩展方法

那段代码很老了.

现代AsyncEx方法是一种扩展方法Task.WaitAsync,如下所示:

var ct = new CancellationTokenSource(TimeSpan.FromSeconds(2)).Token;
await myTask.WaitAsync(ct);
Run Code Online (Sandbox Code Playgroud)

我喜欢API如何结束,因为它更清楚的是它取消了等待,而不是操作本身.

有没有办法在不杀死进程的情况下"杀死"任务?

没有.

理想的解决方案是联系您正在使用的库的作者并让他们添加支持CancellationToken.

除此之外,您正处于"取消无法解决的操作"场景中,可以通过以下方式解决:

  • 将代码放在单独的进程中,并在取消时终止该进程.这是唯一完全安全但最困难的解决方案.
  • 将代码放在单独的应用程序域中,并在取消时卸载该应用程序域.这不是完全安全的; 终止的应用程序域可能导致进程级资源泄漏.
  • 将代码放在单独的线程中,并在取消时终止该线程.这更不安全; 终止的线程可能破坏程序内存.

  • 从 .NET 6 开始,“Task.WaitAsync(CancellationToken)”就出现在 BCL 中 (2认同)