CA2016: Reenviar el parámetro CancellationToken a los métodos que lo usan

Propiedad Valor
Nombre de tipo ForwardCancellationTokenToInvocations
Identificador de la regla CA2016
Título Reenviar el parámetro CancellationToken a los métodos que lo usan
Categoría Confiabilidad
La corrección es problemática o no problemática Poco problemático
Habilitado de forma predeterminada en .NET 8 Como sugerencia

Causa

Esta regla localiza las invocaciones de método que podrían aceptar un parámetro CancellationToken, pero que no pasan ninguno, y sugiere reenviarles CancellationToken del método principal.

Descripción de la regla

Esta regla analiza las definiciones de método que adoptan CancellationToken como el último parámetro y, a continuación, analiza todos los métodos invocados en su cuerpo. Si alguna de las invocaciones de método puede aceptar CancellationToken como el último parámetro, o tener una sobrecarga que adopte CancellationToken como el último parámetro, la regla sugiere usar esa opción alternativamente para asegurarse de que la notificación de cancelación se propague a todas las operaciones que pueden escuchar en ella.

Nota

La regla CA2016 está disponible en todas las versiones de .NET donde el tipo CancellationToken está disponible. Para ver las versiones afectadas, consulte la sección "Se aplica a" de CancellationToken.

Cómo corregir infracciones

Puede corregir las infracciones manualmente o usar la corrección de código disponible en Visual Studio. Mantenga el puntero sobre la bombilla que aparece junto a la invocación del método y seleccione el cambio sugerido.

En el ejemplo siguiente se muestran dos cambios sugeridos:

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

Se puede suprimir una infracción de esta regla si no le preocupa reenviar la notificación de operación cancelada a invocaciones de método inferiores. También puede pasar explícitamente default en C# (Nothing en Visual Basic) o None para suprimir la infracción de la regla.

La regla puede detectar diversas infracciones. En los ejemplos siguientes se muestran casos que la regla puede detectar:

Ejemplo 1

La regla sugerirá el reenvío del parámetro c de MyMethod a la invocación MyMethodWithDefault, ya que el método define un parámetro de token opcional:

using System.Threading;

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

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

Solución:

Reenviar el parámetro c:

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

Si no le preocupa el reenvío de notificaciones de cancelación a invocaciones más bajas, puede:

Pasar explícitamente default:

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

O pasar explícitamente CancellationToken.None:

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

Ejemplo 2

La regla sugerirá el reenvío del parámetro c de MyMethod a la invocación MyMethodWithOverload, ya que el método tiene una sobrecarga que adopta un parámetro 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();
        }
    }
}

Solución:

Reenviar el parámetro c:

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

Si no le preocupa el reenvío de notificaciones de cancelación a invocaciones más bajas, puede:

Pasar explícitamente default:

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

O pasar explícitamente CancellationToken.None:

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

Ejemplos de no infracción

El parámetro CancellationToken del método principal no está en la última posición:

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();
        }
    }
}

El parámetro CancellationToken del método predeterminado no está en la última posición:

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();
        }
    }
}

El parámetro CancellationToken del método de sobrecarga no está en la última posición:

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();
        }
    }
}

El método principal define más de un parámetro 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();
        }
    }
}

El método principal con valores predeterminados define más de un parámetro 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();
        }
    }
}

La sobrecarga de método define más de un parámetro 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();
        }
    }
}

Supresión de una advertencia

Si solo quiere suprimir una única infracción, agregue directivas de preprocesador al archivo de origen para deshabilitar y volver a habilitar la regla.

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

Para deshabilitar la regla de un archivo, una carpeta o un proyecto, establezca su gravedad en none del archivo de configuración.

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

Para obtener más información, consulte Procedimiento para suprimir advertencias de análisis de código.