Бөлісу құралы:


CA2016: Передавайте параметр CancellationToken в методы, которые его принимают

Свойство Значение
Имя типа ПереадресоватьТокенОтменыВВызовы
Идентификатор правила CA2016
Заголовок Переадресовывать параметр CancellationToken методам, которые его принимают
Категория Надежность
Исправление является критическим или не критическим неразрывный
Включен по умолчанию в .NET 10 Как предложение
Применимые языки C# и Visual Basic

Причина

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

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

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

Примечание.

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

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

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

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

Правило CA2016: переадресовывать параметр CancellationToken методам, которые его принимают

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

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

Пример 1

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

using System.Threading;

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

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

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

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

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

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

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

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

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

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

Пример 2

Правило предложит переслать параметр ct из 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 ct)
        {
            MyMethodWithOverload();
        }
    }
}

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

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

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

Если вас не беспокоит пересылка уведомлений об отмене вызовов в зависимости уровня, вы можете либо:

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

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

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

public static void MyMethod(CancellationToken ct)
{
    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 ct, 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 ct)
        {
            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 ct)
        {
            MyMethodWithOverload();
        }
    }
}

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

using System.Threading;

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

        public static void MyMethod(CancellationToken ct1, CancellationToken ct2)
        {
            MyMethodWithDefault();
        }
    }
}

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

using System.Threading;

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

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

Перегрузка метода определяет более чем один параметр CancellationToken.

using System.Threading;

namespace ConsoleApp
{
    public static class MyTestClass
    {
        public static void MyMethodWithOverload(CancellationToken ct1, CancellationToken ct2)
        {
        }

        public static void MyMethodWithOverload()
        {
        }

        public static void MyMethod(CancellationToken ct)
        {
            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

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