CA2016: переадресация параметра CancellationToken в методы, которые принимают один

Свойство Значение
Имя типа ForwardCancellationTokenToInvocations
Идентификатор правила CA2016
Заголовок Переадресовывать параметр CancellationToken методам, которые его принимают
Категория Надежность
Исправление является критическим или не критическим Не критическое
Включен по умолчанию в .NET 8 Как предложение

Причина

Это правило находит вызовы методов, которые могут принимать параметр CancellationToken, но не передают его. Оно предлагает переадресовывать им CancellationToken родительского метода.

Описание правила

Это правило анализирует определения методов, которые принимают CancellationToken в качестве последнего параметра, затем анализирует все методы, вызываемые в его теле. Если какой-либо вызов метода может принять CancellationToken в качестве последнего параметра или у него есть перегрузка, которая принимает CancellationToken в качестве последнего параметра, правило предлагает использовать этот параметр вместо того, чтобы убедиться, что уведомление об отмене распространяется на все операции, которые могут его прослушивать.

Примечание.

Правило CA2016 доступно во всех версиях .NET, где доступен тип CancellationToken. Сведения о применимых версиях см. в разделе "Применение к" в разделе "ОтменаToken".

Устранение нарушений

Вы можете исправить нарушения вручную или использовать исправление кода, доступное в Visual Studio. Наведите указатель мыши на лампочку, которая отображается рядом с вызовом метода и выберите предлагаемое изменение.

В следующем примере показаны два предлагаемых изменения.

Rule CA2016 - Forward the CancellationToken parameter to methods that take one

Вывод предупреждений для этого правила можно отключить, если вас не беспокоит сокращение числа вызовов методов из-за пересылки уведомлений об отмене операций. Кроме того, можно явным образом передать default в C# (Nothing в Visual Basic) или None.

Правило может обнаруживать различные нарушения. Ниже приведены примеры случаев, которые может обнаруживать это правило.

Пример 1

Правило предложит переслать параметр c из MyMethod в вызов MyMethodWithDefault, так как метод определяет дополнительный параметр токена:

using System.Threading;

namespace ConsoleApp
{
    public static class MyTestClass
    {
        public static void MyMethodWithDefault(CancellationToken ct = default)
        {
        }

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithDefault();
        }
    }
}

Исправление:

Перешлите параметр c:

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithDefault(c);
        }

Если вас не беспокоит сокращение числа вызовов методов из-за пересылки уведомлений об отмене, можно выполнить одно из следующих действий.

Явным образом передайте default:

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithDefault(default);
        }

Или явным образом передайте CancellationToken.None:

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithDefault(CancellationToken.None);
        }

Пример 2

Правило предложит переслать параметр c из MyMethod в вызов MyMethodWithOverload, так как у метода есть перегрузка, которая принимает параметр CancellationToken:

using System.Threading;

namespace ConsoleApp
{
    public static class MyTestClass
    {
        public static void MyMethodWithOverload()
        {
        }

        public static void MyMethodWithOverload(CancellationToken ct = default)
        {
        }

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithOverload();
        }
    }
}

Исправление:

Перешлите параметр c:

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithOverload(c);
        }

Если вас не беспокоит сокращение числа вызовов методов из-за пересылки уведомлений об отмене, можно выполнить одно из следующих действий.

Явным образом передайте default:

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithOverload(default);
        }

Или явным образом передайте CancellationToken.None:

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithOverload(CancellationToken.None);
        }

Примеры ненарушений

Параметр CancellationToken в родительском методе не находится в последней позиции:

using System.Threading;

namespace ConsoleApp
{
    public static class MyTestClass
    {
        public static void MyMethodWithDefault(CancellationToken ct = default)
        {
        }

        public static void MyMethod(CancellationToken c, int lastParameter)
        {
            MyMethodWithDefault();
        }
    }
}

Параметр CancellationToken в методе по умолчанию не находится в последней позиции:

using System.Threading;

namespace ConsoleApp
{
    public static class MyTestClass
    {
        public static void MyMethodWithDefault(CancellationToken ct = default, int lastParameter = 0)
        {
        }

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithDefault();
        }
    }
}

Параметр CancellationToken в методе перегрузки не находится в последней позиции:

using System.Threading;

namespace ConsoleApp
{
    public static class MyTestClass
    {
        public static void MyMethodWithOverload(int lastParameter)
        {
        }
        public static void MyMethodWithOverload(CancellationToken ct, int lastParameter)
        {
        }

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithOverload();
        }
    }
}

Родительский метод определяет несколько параметров CancellationToken:

using System.Threading;

namespace ConsoleApp
{
    public static class MyTestClass
    {
        public static void MyMethodWithDefault(CancellationToken ct = default)
        {
        }

        public static void MyMethod(CancellationToken c1, CancellationToken c2)
        {
            MyMethodWithDefault();
        }
    }
}

Метод с настройками по умолчанию определяет несколько параметров CancellationToken:

using System.Threading;

namespace ConsoleApp
{
    public static class MyTestClass
    {
        public static void MyMethodWithDefault(CancellationToken c1 = default, CancellationToken c2 = default)
        {
        }

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithDefault();
        }
    }
}

Перегрузка метода определяет несколько параметров CancellationToken:

using System.Threading;

namespace ConsoleApp
{
    public static class MyTestClass
    {
        public static void MyMethodWithOverload(CancellationToken c1, CancellationToken c2)
        {
        }

        public static void MyMethodWithOverload()
        {
        }

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithOverload();
        }
    }
}

Отключение предупреждений

Если вы просто хотите отключить одно нарушение, добавьте директивы препроцессора в исходный файл, чтобы отключить и повторно включить правило.

#pragma warning disable CA2016
// The code that's violating the rule is on this line.
#pragma warning restore CA2016

Чтобы отключить правило для файла, папки или проекта, задайте его серьезность none в файле конфигурации.

[*.{cs,vb}]
dotnet_diagnostic.CA2016.severity = none

Дополнительные сведения см. в разделе Практическое руководство. Скрытие предупреждений анализа кода.