Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
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 '
T' en lugar de 'Task<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. - CS4001: no se puede esperar expresión.
-
CS4003: '
await' no se puede usar como identificador dentro de un método asincrónico o una expresión lambda. - CS4005: los métodos asincrónicos no pueden tener parámetros de tipo de puntero.
- CS4006: no se permite __arglist en la lista de parámetros de métodos asincrónicos.
-
CS4007: La instancia de tipo no se puede conservar en el límite "
await" o "yield". -
CS4008: no se puede esperar '
void'. - CS4009: un punto de entrada nulo o int que devuelve no puede ser asincrónico.
- CS4010: no se puede convertir la expresión asincrónica al tipo delegado. Una expresión asincrónica puede devolver void, Task o Task<T>, ninguno de los cuales se puede convertir al tipo.
-
CS4011: '
await' requiere que el tipo de retorno de '{1}.GetAwaiter()' tenga miembros adecuados 'IsCompleted', 'OnCompleted' y 'GetResult', e implemente 'INotifyCompletion' o 'ICriticalNotifyCompletion'. - CS4012: Los parámetros de tipo no se pueden declarar en métodos asincrónicos ni expresiones lambda asincrónicas.
-
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
awaitoperador al resultado de la llamada. - CS4015: 'MethodImplOptions.Synchronized' no se puede aplicar a un método asincrónico.
- CS4016: Dado que se trata de un método asincrónico, la expresión de retorno debe ser de un tipo similar a Task en lugar del tipo declarado.
- CS4027: el tipo de expresión no implementa el miembro necesario.
-
CS4028: "
await" requiere que el tipo disponga de un método "GetAwaiter" adecuado. ¿Falta una directiva using para "System"? - CS4029: no se puede devolver una expresión de tipo 'void'.
- CS4030: El atributo security no se puede aplicar a un método asincrónico.
- CS4031: los métodos asincrónicos no se permiten en un atributo Interface, Class o Structure que tenga el atributo "SecurityCritical" o "SecuritySafeCritical".
-
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'. -
CS4034: 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". - CS8031: La expresión lambda asincrónica, al ser convertida en un delegado que devuelve una tarea, no puede devolver un valor.
-
CS8100: el operador '
await' no se puede usar en un inicializador de variable de script estático. - CS8177: los métodos asincrónicos no pueden tener variables locales de referencia.
-
CS8178: no se puede conservar una referencia devuelta por una llamada al método a través del límite "
await" o "yield". - CS8204: Para que el tipo pueda ser utilizado como AsyncMethodBuilder para el tipo objetivo, su propiedad Task debería devolver el tipo objetivo en lugar del tipo declarado.
-
CS8403: el método con un bloque de iterador debe ser '
async' para devolver IAsyncEnumerable<T>. - CS8411: la instrucción foreach asincrónica no puede funcionar en variables de tipo porque el tipo no contiene una definición de extensión o instancia pública adecuada para el miembro necesario.
- CS8892: el método no se usará como punto de entrada porque se encontró un punto de entrada sincrónico.
- CS8935: El atributo AsyncMethodBuilder no se permite en métodos anónimos sin un tipo de valor devuelto explícito.
- CS8940: Se esperaba un tipo de retorno genérico similar a una tarea, pero el tipo encontrado en el atributo "AsyncMethodBuilder" no era adecuado. Debe ser un tipo genérico sin vincular con aridad uno, y su tipo contenedor (si existe) debe ser no genérico.
-
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'. -
CS4034: 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". -
CS8178: no se puede conservar una referencia devuelta por esta llamada a través del límite "
await" o "yield". - CS8411: la instrucción foreach asincrónica no puede funcionar en variables de tipo porque el tipo no contiene una definición de extensión o instancia pública adecuada para el miembro necesario.
- CS4001: No se puede usar 'await' en la expresión.
-
CS4003: '
await' no se puede usar como identificador dentro de un método asincrónico o una expresión lambda. -
CS4007: La instancia de tipo no se puede conservar en el límite "
await" o "yield". CS4011 :' ' requiere que el tipo de valor devuelto de tenga los miembros 'IsCompleted', 'OnCompleted' y 'GetResult' e implemente 'INotifyCompletion' o 'ICriticalNotifyCompletion'. - CS4027: El tipo no implementa el miembro requerido.
-
CS4028: "
await" requiere que el tipo tenga un método "GetAwaiter" adecuado. ¿Está faltando una directiva "using" para "System"? -
CS8100: el operador '
await' no se puede usar en un inicializador de variable de script estático.
Los siguientes elementos explican cómo corregir cada error. Para obtener más información sobre el await operador y el patrón awaiter, consulte Programación asincrónica con async y await.
- Agregue el
asyncmodificador al método o expresión lambda que contiene laawaitexpresión (CS1992, CS4032, CS4033, CS4034). El compilador requiere elasyncmodificador para que pueda generar la máquina de estado que controla la suspensión asincrónica y la reanudación. Las tres variantes de este error proporcionan sugerencias específicas del contexto para el tipo de valor devuelto correcto. - Mueva
awaitlas expresiones fuera decatchlos bloques cuando tenga como objetivo C# 5 o versiones anteriores (CS1985). A partir de C# 6, el compilador admiteawaiten bloquescatchyfinally. Este error ya no se genera en C# 6 y versiones posteriores. - Mueva
awaitlas expresiones fuera de los bloques delockdeclaraciones (CS1996). La suspensión asincrónica mientras mantiene un bloqueo corre el riesgo de interbloqueos. El bloqueo se mantiene entre conmutadores de subproceso donde otro código podría estar esperando el mismo bloqueo. - Reestructura las expresiones de consulta para que
awaitsolo aparezcan en la primera expresión de colección de la cláusula inicialfromo en la expresión de colección de unajoincláusula (CS1995). Otras cláusulas de consulta se traducen en expresiones lambda que no admiten suspensión asincrónica. - Cambie el tipo de la expresión esperada para que exponga un método accesible
GetAwaiter()que siga el patrón awaiter (CS1986, CS4028). El tipo puede implementar el patrón directamente o a través de un método de extensión. Si elGetAwaitermétodo existe, pero falta unausingdirectiva paraSystem, el compilador genera el mensaje CS4028 más específico en lugar de CS1986. - Asegúrese de que el tipo awaiter devuelto por
GetAwaiter()tieneIsCompletedmiembros ,OnCompletedyGetResulte implementa INotifyCompletion o ICriticalNotifyCompletion (CS4011, CS4027). Laawaitexpresión depende de estos miembros para comprobar el estado de finalización, registrar continuaciones y recuperar resultados. - Cambie el tipo de valor devuelto del método llamado de
voida Task o Task<TResult> para que se pueda esperar el resultado (CS4008). No se puede esperar a unvoidmétodo de devolución porque no hay ningún objeto de tarea para realizar un seguimiento de la finalización o propagar excepciones. - Cambie la expresión esperada a un tipo que admita el patrón awaiter (CS4001). Los tipos como
int,stringy otros tipos integrados no tienen unGetAwaitermétodo y no se pueden esperar directamente. - Almacene el resultado de una llamada al método que devuelve referencias en una variable local antes de usar
await(CS8178). Una referencia devuelta por un método no se puede conservar a través de unaawaitfrontera porque la máquina de estados asincrónica puede suspenderse y reanudarse en otro hilo o contexto, invalidando la referencia. - Implemente IAsyncEnumerable<T> en el tipo de colección o agregue un método accesible
GetAsyncEnumeratorque devuelva un tipo conCurrentmiembros yMoveNextAsync(CS8411). Laawait foreachinstrucción requiere que el tipo de colección siga el patrón enumerable asincrónico. - Cambie el nombre de cualquier variable o parámetro local denominado
awaitdentro de unasyncmétodo o expresión lambda (CS4003). Dentro de contextos asincrónicos,awaites una palabra clave contextual y no se puede usar como identificador. - Mueva la
awaitexpresión fuera del inicializador de la variable de script estático y a un cuerpo del método (CS8100). Los inicializadores estáticos se ejecutan fuera de un contexto asincrónico, por lo queawaitno está disponible en esa ubicación. - Reestructurar el código de modo que las instancias
ref structno necesiten conservarse a través de un límiteawaitoyield(CS4007). La máquina de estado asincrónica almacena variables locales en el montón, y los tiposref structestán diseñados para estar ligados a la pila; no se pueden mover de forma segura a la memoria del montón entre puntos de suspensión.
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 del tipo "T" en lugar de "
Task<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.
- CS8935: El atributo AsyncMethodBuilder no se permite en métodos anónimos sin un tipo de valor devuelto explícito.
- CS8940: Se esperaba un tipo genérico de retorno similar a una tarea, pero el tipo encontrado en el atributo 'AsyncMethodBuilder' no era adecuado. Debe ser un tipo genérico no vinculado de aridad uno, y su tipo contenedor (si existe) debe ser no genérico.
-
CS8403: el método con un bloque de iterador debe ser '
async' para devolver '{1}'. -
CS9330: '
MethodImplAttribute.Async' no se puede aplicar manualmente a los métodos. Marque el método 'async'. - CS4005: los métodos asincrónicos no pueden tener parámetros de tipo de puntero.
- CS4006: no se permite __arglist en la lista de parámetros de métodos asincrónicos.
- CS4010: No se puede convertir lambda asincrónica al tipo delegado. Una expresión lambda asincrónica puede devolver void, Task o Task<T>, ninguna de las cuales se puede convertir al tipo devuelto.
- CS4012: Los parámetros de tipo no se pueden declarar en métodos asincrónicos ni expresiones lambda asincrónicas.
- CS4015: 'MethodImplOptions.Synchronized' no se puede aplicar a un método asincrónico.
- CS4016: dado que se trata de un método asincrónico, la expresión de retorno debe ser de tipo de tarea en lugar de tipo.
- CS8031: La expresión lambda asíncrona convertida en un delegado que devuelve tareas no puede devolver un valor.
- CS8204: Para que un tipo se utilice como AsyncMethodBuilder para otro tipo, su propiedad Task debe devolver el tipo requerido en lugar del tipo declarado.
Los siguientes elementos explican cómo corregir cada error. Para obtener más información sobre las declaraciones de métodos async, consulte el modificador
- Cambie la expresión de retorno para que coincida con el tipo de resultado subyacente del método asincrónico (CS1983, CS4016). Cuando un método asincrónico devuelve
Task<T>, lareturninstrucción debe proporcionar un valor de tipoT, noTask<T>, porque la máquina de estado generada por el compilador ajusta automáticamente el valor en un objeto Task. CS1983 aparece cuando el método devuelveTask<T>y la expresión esT; CS4016 cubre el caso general en el que el tipo de expresión de retorno no coincide. - Quite el
asyncmodificador de los métodos que no tienen un cuerpo, como métodos abstractos o declaraciones de métodos de interfaz (CS1994). Elasyncmodificador requiere un cuerpo del método para que el compilador pueda generar la implementación de la máquina de estado. - Cambie el tipo de valor devuelto de un punto de entrada asincrónico a Task o Task<TResult> (CS4009). A partir de C# 7.1, el
Mainmétodo puede serasync, pero debe devolverTaskoTask<int>-async voidyasync intno son firmas de punto de entrada válidas. - Quite o cambie el nombre de un punto de entrada cuando el proyecto contenga un método sincrónico y asincrónico
Main(CS8892). El compilador selecciona el punto de entrada sincrónico y emite esta advertencia para el candidato asincrónico que omite. - Agregue un tipo de valor devuelto explícito a la expresión lambda antes de aplicar el
[AsyncMethodBuilder]atributo (CS8935). El compilador no puede resolver el tipo de generador para un método anónimo cuyo tipo de valor devuelto se infiere, ya que el atributo debe coincidir con un tipo de valor devuelto específico en tiempo de compilación. - Cambie el tipo especificado en el atributo
[AsyncMethodBuilder]a un tipo genérico sin enlazar como uno de aridad, comoMyTaskMethodBuilder<>en lugar deMyTaskMethodBuilder<T>o un tipo no genérico (CS8940). El tipo que contiene el generador, si lo hay, también debe ser no genérico. El compilador requiere esta forma para que pueda construir el patrón para cualquier tipo de retorno de tipo tarea concreto. - Reemplace el atributo manual
[MethodImpl(MethodImplOptions.Async)]por laasyncpalabra clave en la declaración de método (CS9330). LaMethodImplOptions.Asyncmarca está reservada para uso interno en tiempo de ejecución y no se puede aplicar directamente en el código de usuario. - Agregue el
asyncmodificador a los métodos que contienen bloques de iterador y devuelven IAsyncEnumerable<T> o IAsyncEnumerator<T> (CS8403). Sin el modificadorasync, el compilador trata el método como el iterador síncrono y no puede generar la máquina de estados para flujos asíncronos. - Quite los parámetros de tipo de puntero de los métodos asincrónicos (CS4005). Los punteros hacen referencia a ubicaciones de memoria fijas que no se pueden conservar de forma segura en puntos de suspensión asincrónicos en los que la ejecución podría reanudarse en un subproceso diferente.
- Quite
__arglistde las listas de parámetros del método asincrónico (CS4006). Las listas de argumentos de longitud variable dependen de las convenciones de llamada basadas en la pila que no son compatibles con la máquina de estado asincrónica asignada por el montón. - Quite los parámetros
ref,inoout, y los parámetros de tiposref structcomo Span<T> o ReadOnlySpan<T>, de métodos asincrónicos o expresiones lambda asincrónicas (CS4012). Estos tipos de parámetros están enlazados a la pila y no se pueden capturar de forma segura en el cierre de la máquina de estado asincrónica asignada por el montón. - Cambie el tipo de delegado de destino para que coincida con el tipo de valor devuelto de la lambda asincrónica (CS4010). Una expresión lambda asincrónica puede devolver
void, Tasko Task<TResult>, y el compilador no puede convertirlas en tipos de delegado arbitrarios que esperan tipos de valor devuelto diferentes. - Quite la expresión
returnde una lambda asincrónica que está asignada a un delegado sin tipo genérico de retornoTasko cambie el tipo del delegado aFunc<Task<T>>para que la lambda pueda devolver un valor (CS8031). Un delegadoTaskno genérico que devuelve representa una operación asincrónica sin resultado, por lo que devolver un valor genera un desajuste de tipos. - Quite el
[MethodImpl(MethodImplOptions.Synchronized)]atributo de los métodos asincrónicos (CS4015). LaSynchronizedopción adquiere un bloqueo para toda la ejecución del método, pero un método asincrónico suspende y reanuda potencialmente en subprocesos diferentes, lo que hace que la semántica de bloqueo no se defina. - Corrija el tipo personalizado
AsyncMethodBuilderpara que suTaskpropiedad devuelva el mismo tipo que el tipo de valor devuelto declarado del método asincrónico (CS8204). El compilador usa la propiedad del generadorTaskpara obtener el objeto de tarea final, por lo que una falta de coincidencia de tipos impide que la máquina de estados funcione correctamente.
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
awaitoperador al resultado de la llamada. - CS8177: los métodos asincrónicos no pueden tener variables locales de referencia.
-
CS9123: el operador '
&' no debe usarse en parámetros ni variables locales en métodos asincrónicos. - CS4029: no se puede devolver una expresión de tipo 'void'.
- CS4030: El atributo security no se puede aplicar a un método asincrónico.
- CS4031: los métodos asincrónicos no se permiten en un atributo Interface, Class o Structure que tenga el atributo "SecurityCritical" o "SecuritySafeCritical".
Los siguientes elementos explican cómo corregir cada error. Para obtener más información, consulte Programación asincrónica con async y await y el await operador .
- Agregue el
awaitoperador a cada llamada que devuelva Task o Task<TResult>, o descarte explícitamente el resultado con_ =si el comportamiento de disparo y olvido está realmente pensado (CS4014). Sinawait, cualquier excepción producida por la operación asincrónica se pierde silenciosamente y el método de llamada continúa ejecutándose antes de que finalice la operación, lo que puede provocar errores sutiles de ordenación y corrección. - Quite la
returnexpresión de un método asincrónico cuyo tipo de valor devuelto seaTask(no genérico) o cambie el tipo de valor devuelto aTask<T>cuando el método necesite devolver un valor (CS1997). En un método asincrónico que devuelveTask, el compilador genera el contenedor de tareas; devolver un valor es un error de coincidencia de tipos porque la firma del método no promete ningún resultado. - Agregue al menos una
awaitexpresión al cuerpo del método o quite elasyncmodificador y devuelva la tarea directamente (CS1998). Unasyncmétodo sin expresionesawaitse ejecuta completamente sincrónicamente, lo que agrega sobrecarga innecesaria de la máquina de estado. Si el método encapsula intencionadamente una operación sincrónica, quitarasyncy devolver la tarea elimina explícitamente esa sobrecarga. - Vuelva a escribir la expresión lambda para que no use
asynccuando se asigna a un tipo de árbol de expresión comoExpression<Func<...>>(CS1989). Los árboles de expresión representan código como estructuras de datos que el compilador puede analizar o traducir, pero la máquina de estado compleja queasyncgenera no se puede capturar en un árbol de expresiones. - Cambie la implementación del evento para que tanto la declaración de interfaz como la clase de implementación acepten si el evento usa la semántica de Windows Runtime o la semántica de .NET normal (CS1991). Este error se aplica a escenarios de interoperabilidad de Windows Runtime en los que un evento winRT no se puede implementar como un evento de .NET normal o viceversa.
- Quite el operador address-of (
&) de las expresiones que hacen referencia a parámetros o variables locales dentro de métodos asincrónicos (CS9123). La máquina de estado asincrónico podría reubicar variables capturadas en el montón durante la suspensión, lo que invalidaría cualquier puntero obtenido a través de la dirección de . - Quite las variables locales por referencia de los métodos asincrónicos o asegúrese de que no abarcan un
awaitlímite (CS8177). La máquina de estado asincrónico captura variables locales en cierres asignados por el montón y las referencias a ubicaciones de pila no se pueden conservar de forma segura entre puntos de suspensión. En C# 13 y versiones posteriores,reflocales están permitidos en métodos asincrónicos siempre que no crucen un límiteawait, y por lo tanto, no se produce este error. - Quite la instrucción
returnque devuelve el resultado de un método que retornavoid, o cambie el método llamado para que devuelva un valor (CS4029). No se puede usarreturn SomeVoidMethod();porquevoidno es un tipo que se puede devolver como un valor. Quite lareturnpalabra clave y llame al método como una instrucción independiente o cambie la firma del método llamado para devolver un tipo concreto. - Quite atributos de seguridad como
[SecurityCritical]o[SecuritySafeCritical]de métodos asincrónicos (CS4030) o quite elasyncmodificador de los métodos de los tipos marcados con estos atributos (CS4031). Las anotaciones de seguridad de acceso de código se aplican al método declarante, pero la máquina de estado asincrónica generada por el compilador se ejecuta en un contexto independiente donde no se pueden aplicar esas anotaciones de seguridad.