CA1068: параметры CancellationToken должны быть последними

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

Причина

Метод имеет параметр CancellationToken, который не является последним параметром.

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

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

Методы, выполняющие длительные операции или асинхронные операции, которые могут быть отменены, обычно принимают параметр токена отмены. Каждый токен отмены имеет объект CancellationTokenSource, который создает маркер и использует его для отмены вычислений. Обычно существует длинная цепочка вызовов методов, которая передает маркер отмены от вызывающих объектов в вызываемые. Следовательно, большое количество методов, принимающих участие в отменяемых вычислениях, в конечном итоге имеют параметр токена отмены. Однако сам маркер отмены обычно не важен для основных функций большинства этих методов. Считается хорошей практикой разработки API ставить такие параметры последними параметрами в списке.

Особые случаи

Правило CA1068 не срабатывает в следующих особых случаях:

  • Метод имеет один или несколько параметров optional (необязательных) (Optional в Visual Basic) после обязательного параметра токена отмены. Компилятор требует, чтобы все необязательные параметры были определены после всех обязательных параметров.
  • Метод имеет один или несколько параметров ref или out (ByRef в Visual Basic) после параметра токена отмены. Как правило, параметры ref или out помещаются в конце списка, поскольку они обычно указывают выходные значения для метода.

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

Измените сигнатуру метода, чтобы переместить параметр токена отмены в конец списка. В следующих двух фрагментах кода показано нарушение правила и способы его устранения:

// Violates CA1068
public void LongRunningOperation(CancellationToken token, string usefulParameter)
{
    ...
}
// Does not violate CA1068
public void LongRunningOperation(string usefulParameter, CancellationToken token)
{
    ...
}

Когда лучше отключить предупреждения

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

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

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

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

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

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

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

Настройка кода для анализа

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

Эти параметры можно настроить только для этого правила, для всех правил, к которым она применяется, или для всех правил в этой категории (конструктор), к которым она применяется. Дополнительные сведения см. в статье Параметры конфигурации правила качества кода.

Включение определенных контактных зон API

Вы можете настроить, для каких частей базы кода следует выполнять это правило в зависимости от их доступности. Например, чтобы указать, что правило должно выполняться только для закрытой контактной зоны API, добавьте следующую пару "ключ-значение" в файл EDITORCONFIG в своем проекте:

dotnet_code_quality.CAXXXX.api_surface = private, internal

Исключение определенных символов

Вы можете исключить из анализа определенные символы, например типы и методы. Например, чтобы указать, что правило не должно выполняться для какого-либо кода в типах с именем MyType, добавьте следующую пару "ключ-значение" в файл EDITORCONFIG в своем проекте:

dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType

Допустимые форматы имени символа в значении параметра (разделенные |):

  • Только имя символа (включает все символы с этим именем, любого типа и в любом пространстве имен).
  • Полные имена в формате идентификатора документации для символа. Для каждого имени символа требуется префикс в виде символа, например M: для методов, T: для типов и N: для пространств имен.
  • .ctor используется для конструкторов, а .cctor — для статических конструкторов.

Примеры:

Значение параметра Итоги
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType Соответствует всем символам с именем MyType.
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType1|MyType2 Соответствует всем символам с именем MyType1 или MyType2.
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS.MyType.MyMethod(ParamType) Соответствует конкретному методу MyMethod с заданной полной сигнатурой.
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS1.MyType1.MyMethod1(ParamType)|M:NS2.MyType2.MyMethod2(ParamType) Соответствует конкретным методам MyMethod1 и MyMethod2 с соответствующими полными сигнатурами.

Исключить определенные типы и их производные типы

Из анализа можно исключать определенные типы и их производные типы. Например, чтобы указать, что правило не должно выполняться в каких-либо методах типов MyType и их производных типов, добавьте следующую пару "ключ-значение" в файл .editorconfig своего проекта:

dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType

Допустимые форматы имени символа в значении параметра (разделенные |):

Примеры:

Значение параметра Итоги
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType Соответствует всем типам с именем MyType и всем их производным типам.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType1|MyType2 Соответствует всем типам с именем MyType1 или MyType2 и всем их производным типам.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS.MyType Соответствует конкретному типу MyType с заданным полным именем и всем производным от него типам.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS1.MyType1|M:NS2.MyType2 Соответствует конкретным типам MyType1 и MyType2 с заданным полным именем и всем производным от них типам.

См. также