正在捕获TaskCanceledException并检查任务.取消了一个好主意

本文关键字:好主意 一个 取消 任务 TaskCanceledException 检查 | 更新日期: 2023-09-27 18:11:24

我的团队中有一些人非常喜欢异步Task编码。有时他们喜欢使用CancellationToken参数。

我不确定的是我们是否应该作为一个团队使用这种风格的代码(a):

    async Task<someObject> DoStuff(CancellationToken t)
    {
        while (!t.IsCanceled)
        {
            try {
                Task.Delay(5000, t);
            }
            catch (AggregateException e) // or is it TaskCanceledException or OperationCanceledException? I don't know? :)
            {
            }
            // poll something, return someObject, or null
        }
        return null;
    }

这显然意味着调用者应该自己检查取消令牌以确定是否继续处理。然后,当函数因为取消而返回时,它们可能必须处理null的retval值:

    var retVal = await DoStuff(token);
    if (token.IsCanceled) { ... }
然而,如果我们采用第二种风格的代码(B),它依赖于TaskCanceledException:
    async Task<someObject> DoStuff(CancellationToken t)
    {
        while(true)
        {
            Task.Delay(5000, t);
            // poll something, return someObject, or null
        }
    }

实现代码显然更简单——调用者可以选择是否处理异常,视情况而定……但我不禁担心调用者可能会忘记 TaskCanceledException是他们必须担心的事情,进程可能会崩溃,因为他们没有捕捉到这些异常(前台或后台线程)。

所以,我过于乐观的问题是:你认为哪种最好的风格,每个人都应该总是使用,为什么?:)

正在捕获TaskCanceledException并检查任务.取消了一个好主意

在。net框架本身,当你传递一个CancellationToken作为参数,你会得到一个TaskCanceledException。我不会违背这一点,创建我自己的设计模式,因为熟悉。net的人会熟悉你的代码。

我的指导方针是这样的:取消令牌的那个应该处理TaskCanceledException,所以如果你出于自己的原因在你的方法中使用CancellationToken,继续使用try-catch块。但是如果您将令牌作为参数,则让异常被抛出