Compartir vía


Resolución de errores y advertencias en métodos asincrónicos mediante el operador await

En este artículo se tratan los siguientes errores del compilador:

  • CS1983: Dado que se trata de un método asincrónico, la expresión de retorno debe ser de tipo 'Task<T>' en lugar de 'T'.
  • CS1985: No se puede usar 'await' en un bloque catch.
  • CS1986: 'await' requiere que el tipo tenga un método 'GetAwaiter' adecuado.
  • CS1989: las expresiones lambda asincrónicas no se pueden convertir en árboles de expresión.
  • CS1991: "Type" no puede implementar "event" porque es un evento de Windows Runtime y "event" es un evento de .NET normal.
  • CS1992: el operador 'await' solo se puede usar cuando se incluye dentro de un método o expresión lambda marcada con el modificador 'async'.
  • CS1994: el modificador 'async' solo se puede usar en métodos que tienen un cuerpo.
  • CS1995: el operador 'await' solo se puede usar en una expresión de consulta dentro de la primera expresión de colección de la cláusula inicial 'from' o dentro de la expresión de colección de una cláusula 'join'.
  • CS1996: No se puede utilizar 'await' en el bloque de una instrucción lock.
  • CS1997: Dado que function es un método asincrónico que devuelve un valor, una palabra clave return no debe ir seguida de una expresión de objeto.
  • CS1998: este método asincrónico carece de operadores "await" y se ejecutará sincrónicamente. Considere la posibilidad de usar el operador "await" para esperar llamadas API sin bloqueo o "await Task.Run(...)" para realizar el trabajo enlazado a la CPU en un subproceso en segundo plano.
  • CS4008: no se puede esperar 'void'.
  • CS4009: un punto de entrada nulo o int que devuelve no puede ser asincrónico.
  • CS4014: dado que no se espera esta llamada, la ejecución del método actual continúa antes de que se complete la llamada. Considere la posibilidad de aplicar el await operador al resultado de la llamada.
  • CS4032: el operador 'await' solo se puede usar dentro de un método asincrónico. Considere la posibilidad de marcar este método con el modificador "async" y cambiar su tipo de valor devuelto a "Task<T>".
  • CS4033: el operador 'await' solo se puede usar dentro de un método asincrónico. Considere la posibilidad de marcar este método con el modificador 'async' y cambiar su tipo de valor devuelto a 'Task'.
  • CS8892: el método no se usará como punto de entrada porque se encontró un punto de entrada sincrónico.
  • CS9123: el operador '&' no debe usarse en parámetros ni variables locales en métodos asincrónicos.
  • CS9330: 'MethodImplAttribute.Async' no se puede aplicar manualmente a los métodos. Marque el método "async".

Requisitos para las expresiones await

  • CS1985: No puede utilizarse 'await' en una cláusula catch.
  • CS1986: 'await' requiere que el tipo tenga un método 'GetAwaiter' adecuado.
  • CS1992: el operador 'await' solo se puede usar cuando se incluye dentro de un método o expresión lambda marcada con el modificador 'async'.
  • CS1995: el operador 'await' solo se puede usar en una expresión de consulta dentro de la primera expresión de colección de la cláusula inicial 'from' o dentro de la expresión de colección de una cláusula 'join'.
  • CS1996: No se puede utilizar await en el cuerpo de una instrucción lock.
  • CS4008: no se puede esperar 'void'.
  • CS4032: el operador 'await' solo se puede usar dentro de un método asincrónico. Considere la posibilidad de marcar este método con el modificador 'async' y cambiar su tipo de valor devuelto a 'Task<T>'.
  • CS4033: el operador 'await' solo se puede usar dentro de un método asincrónico. Considere la posibilidad de marcar este método con el modificador 'async' y cambiar su tipo de valor devuelto a 'Task'.

Para usar el await operador correctamente, siga estas reglas. Para obtener más información, consulte Programación asincrónica con async y await.

  • No use await en cláusulas de captura (CS1985). Aunque puede usar await en los bloques try y bloques finally (en C# 6 y versiones posteriores), los bloques catch presentan desafíos especiales con el manejo de excepciones y el flujo de control.
  • No use await dentro de los bloques de instrucciones (CS1996). El compilador no admite esto para evitar emitir código propenso a interbloqueos.
  • Use await solo en ubicaciones específicas dentro de expresiones de consulta (CS1995): dentro de la primera expresión de colección de datos de la cláusula inicial from, o en la expresión de colección de datos de una cláusula join.
  • Marque métodos o expresiones lambda con el async modificador antes de usar await (CS1992, CS4032, CS4033).
  • Asegúrese de que los tipos esperados tienen un método accesible GetAwaiter que devuelve un tipo awaiter (CS1986).
  • No se aplique await a expresiones de tipo void (CS4008).
  • Cambie el tipo de valor devuelto a Task para los métodos que no devuelven un valor o Task<T> para los métodos que devuelven un valor.

Requisitos de firma de método asíncrono

  • CS1983: Dado que se trata de un método asincrónico, la expresión de retorno debe ser de tipo 'Task<T>' en lugar de 'T'.
  • CS1994: el modificador 'async' solo se puede usar en métodos que tienen un cuerpo.
  • CS4009: un punto de entrada nulo o int que devuelve no puede ser asincrónico.
  • CS8892: el método no se usará como punto de entrada porque se encontró un punto de entrada sincrónico.
  • CS9330: 'MethodImplAttribute.Async' no se puede aplicar manualmente a los métodos. Marque el método 'async'.

Para declarar correctamente los métodos asincrónicos, siga estos requisitos de firma. Para obtener más información, consulte Valores de retorno del método asincrónico main.

  • Devuelve uno de los tipos válidos: void, Task, Task<T>, un tipo similar a tareas, IAsyncEnumerable<T>o IAsyncEnumerator<T> (CS1983).
  • Use el async modificador solo en métodos con un cuerpo (CS1994). Quite el async modificador en métodos abstractos en interfaces o clases.
  • Actualice a C# 7.1 o posterior para usar async en el punto de entrada Main, o evite usar async en puntos de entrada en versiones anteriores (CS4009).
  • Quite los puntos de entrada sincrónicos si tiene puntos de entrada sincrónicos y asincrónicos (CS8892).
  • Use la async palabra clave en lugar de aplicar MethodImplAttribute.Async manualmente (CS9330).

Prácticas asincrónicas

  • CS1989: las expresiones lambda asincrónicas no se pueden convertir en árboles de expresión.
  • CS1991: "Type" no puede implementar "event" porque es un evento de Windows Runtime y "event" es un evento de .NET normal.
  • CS1997: Dado que function es un método asincrónico que devuelve un valor, una palabra clave return no debe ir seguida de una expresión de objeto.
  • CS1998: este método asincrónico carece de operadores "await" y se ejecutará sincrónicamente. Considere la posibilidad de usar el operador "await" para esperar llamadas API sin bloqueo o "await Task.Run(...)" para realizar el trabajo enlazado a la CPU en un subproceso en segundo plano.
  • CS4014: dado que no se espera esta llamada, la ejecución del método actual continúa antes de que se complete la llamada. Considere la posibilidad de aplicar el await operador al resultado de la llamada.
  • CS9123: el operador '&' no debe usarse en parámetros ni variables locales en métodos asincrónicos.

Para escribir código asincrónico correctamente y evitar problemas comunes, siga estos procedimientos recomendados. Para obtener más información, consulte Programación asincrónica con async y await.

  • Siempre espera llamadas a métodos asincrónicos que devuelven Task o Task<TResult> (CS4014). Las llamadas no esperadas pueden provocar excepciones perdidas y un comportamiento inesperado.
  • No devuelva un valor de métodos asincrónicos que devuelvan Task (no genérico); use Task<T> en su lugar (CS1997).
  • Incluya al menos un await operador en métodos asincrónicos o quite el async modificador (CS1998).
  • Quite la return instrucción si el método debe devolver Task (CS1997, CS1998).
  • Cambie el tipo de valor devuelto del método a Task<T> para devolver un valor (CS1997, CS1998).
  • Quite el async modificador y devuelva la tarea directamente si no necesita la máquina de estado asincrónico (CS1997, CS1998).
  • No use métodos asincrónicos en árboles de expresión (CS1989). Los árboles de expresión representan código como datos y no admiten las transformaciones complejas de la máquina de estado requeridas por los métodos asincrónicos.
  • No marque los descriptores de acceso Add o Remove en una interfaz o evento WinRT como Asincrónico (CS1991). Se trata de una restricción específica de la plataforma para la interoperabilidad de Windows Runtime.
  • Evite usar el operador address-of (&) en expresiones dentro de métodos asincrónicos (CS9123). El destino se puede reubicar en memoria durante la suspensión, lo que hace que el puntero no sea válido.