在没有CancellationToken的情况下停止任务 [英] Stopping a task without a CancellationToken

查看:193
本文介绍了在没有CancellationToken的情况下停止任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using an external library that has async methods, but not CancellationToken overloads.

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

Now currently I am using an extension method from another StackOverflow question to add a 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;
    }

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

However the underlying task still executes to completion. This wouldn't be much of a problem, but sometimes the underlying task never completes and consumes 99% of my CPU.

有什么办法可以在不终止进程的情况下杀死"任务?

Is there any way to "kill" the task without killing the process?

推荐答案

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

I am using an extension method from another StackOverflow question

该代码很旧.

现代的AsyncEx方法是扩展方法Task.WaitAsync,看起来像这样:

The modern AsyncEx approach is an extension method Task.WaitAsync, which looks like this:

var ct = new CancellationTokenSource(TimeSpan.FromSeconds(2)).Token;
await myTask.WaitAsync(ct);

我喜欢API的结局,因为很明显取消的是 wait ,而不是操作本身.

I like how the API ended up because it's more clear that it's the wait that is cancelled, not the operation itself.

有什么办法可以在不终止进程的情况下杀死"任务?

Is there any way to "kill" the task without killing the process?

否.

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

The ideal solution is to contact the authors of the library you're using and have them add support for CancellationToken.

除此之外,您处于取消不可取消的操作"方案中,可以通过以下方法解决:

Other than that, you're in the "cancel an uncancelable operation" scenario, which can be solved by:

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

这篇关于在没有CancellationToken的情况下停止任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆