Partilhar via


Resolver erros e avisos em métodos assíncronos usando o operador await

Este artigo aborda os seguintes erros do compilador:

  • CS1983: Como este é um método assíncrono, a expressão de retorno deve ser do tipo 'Task<T>' em vez de 'T'.
  • CS1985: Não é possível aguardar numa cláusula de captura.
  • CS1986: 'await' requer que o tipo tenha um método 'GetAwaiter' adequado.
  • CS1989: Expressões lambda assíncronas não podem ser convertidas em árvores de expressão.
  • CS1991: 'Type' não pode implementar 'event' porque é um evento do Tempo de Execução do Windows e 'event' é um evento .NET regular.
  • CS1992: O operador 'await' só pode ser usado quando contido em um método ou expressão lambda marcada com o modificador 'async'.
  • CS1994: O modificador 'async' só pode ser usado em métodos que tenham um corpo.
  • CS1995: O operador 'await' só pode ser usado em uma expressão de consulta dentro da primeira expressão de coleção da cláusula 'from' inicial ou dentro da expressão de coleção de uma cláusula 'join'.
  • CS1996: Não pode esperar no corpo de uma declaração de bloqueio.
  • CS1997: Como a função é um método assíncrono que retorna um valor, uma palavra-chave de retorno não deve ser seguida por uma expressão de objeto.
  • CS1998: Este método assíncrono não tem operadores 'await' e será executado de forma síncrona. Considere usar o operador 'await' para aguardar chamadas de API sem bloqueio, ou 'await Task.Run(...)' para fazer trabalho vinculado à CPU em um thread em segundo plano.
  • CS4008: Não é possível esperar 'void'.
  • CS4009: Um ponto de entrada de retorno nulo ou int não pode ser assíncrono.
  • CS4014: Como essa chamada não é esperada, a execução do método atual continua antes que a chamada seja concluída. Considere aplicar o await operador ao resultado da chamada.
  • CS4032: O operador 'await' só pode ser usado dentro de um método assíncrono. Considere marcar esse método com o modificador 'async' e alterar seu tipo de retorno para 'Task<T>'.
  • CS4033: O operador 'await' só pode ser usado dentro de um método assíncrono. Considere marcar esse método com o modificador 'async' e alterar seu tipo de retorno para 'Task'.
  • CS8892: O método não será usado como um ponto de entrada porque um ponto de entrada síncrono foi encontrado.
  • CS9123: O operador '&' não deve ser usado em parâmetros ou variáveis locais em métodos assíncronos.
  • CS9330: 'MethodImplAttribute.Async' não pode ser aplicado manualmente a métodos. Marque o método 'async'.

Aguarde os requisitos de expressão

  • CS1985: Não é possível usar 'await' numa cláusula de captura.
  • CS1986: 'await' requer que o tipo tenha um método 'GetAwaiter' adequado.
  • CS1992: O operador 'await' só pode ser usado quando contido em um método ou expressão lambda marcada com o modificador 'async'.
  • CS1995: O operador 'await' só pode ser usado em uma expressão de consulta dentro da primeira expressão de coleção da cláusula 'from' inicial ou dentro da expressão de coleção de uma cláusula 'join'.
  • CS1996: Não pode esperar no corpo de uma declaração de bloqueio.
  • CS4008: Não é possível esperar 'void'.
  • CS4032: O operador 'await' só pode ser usado dentro de um método assíncrono. Considere marcar esse método com o modificador 'async' e alterar seu tipo de retorno para 'Task<T>'.
  • CS4033: O operador 'await' só pode ser usado dentro de um método assíncrono. Considere marcar esse método com o modificador 'async' e alterar seu tipo de retorno para 'Task'.

Para usar o await operador corretamente, siga estas regras. Para obter mais informações, consulte Programação assíncrona com async e await.

  • Não utilize await nas cláusulas de captura (CS1985). Embora você possa usar await em blocos try e blocos finally (em C# 6 e posteriores), os blocos catch apresentam desafios especiais com a manipulação de exceções e o fluxo de controle.
  • Não use await dentro de blocos de instrução lock (CS1996). O compilador não suporta isto para evitar a geração de código propenso a deadlocks.
  • Use await somente em locais específicos dentro de expressões de consulta (CS1995): dentro da primeira expressão de coleção da cláusula inicial from , ou dentro da expressão de coleção de uma join cláusula.
  • Marque métodos ou expressões lambda com o async modificador antes de usar await (CS1992, CS4032, CS4033).
  • Verifique se os tipos aguardados têm um método acessível GetAwaiter que retorna um tipo awaiter (CS1986).
  • Não se aplica await a expressões do tipo void (CS4008).
  • Altere o tipo de retorno para Task métodos que não retornam um valor ou Task<T> para métodos que retornam um valor.

Requisitos de assinatura do método assíncrono

  • CS1983: Como este é um método assíncrono, a expressão de retorno deve ser do tipo 'Task<T>' em vez de 'T'.
  • CS1994: O modificador 'async' só pode ser usado em métodos que tenham um corpo.
  • CS4009: Um ponto de entrada de retorno nulo ou int não pode ser assíncrono.
  • CS8892: O método não será usado como um ponto de entrada porque um ponto de entrada síncrono foi encontrado.
  • CS9330: 'MethodImplAttribute.Async' não pode ser aplicado manualmente a métodos. Marque o método 'async'.

Para declarar métodos assíncronos corretamente, siga estes requisitos de assinatura. Para obter mais informações, consulte Valores de retorno principais assíncronos.

  • Retorna um dos tipos válidos: void, Task, Task<T>, um tipo de tarefa, IAsyncEnumerable<T>ou IAsyncEnumerator<T> (CS1983).
  • Use o async modificador apenas em métodos com um corpo (CS1994). Remova o async modificador em métodos abstratos em interfaces ou classes.
  • Atualize para C# 7.1 ou superior para usar async no Main ponto de entrada ou evite usar async em pontos de entrada em versões anteriores (CS4009).
  • Remova os pontos de entrada síncronos se você tiver pontos de entrada sincronizados e assíncronos (CS8892).
  • Use a async palavra-chave em vez de aplicar MethodImplAttribute.Async manualmente (CS9330).

Práticas assíncronas

  • CS1989: Expressões lambda assíncronas não podem ser convertidas em árvores de expressão.
  • CS1991: 'Type' não pode implementar 'event' porque é um evento do Tempo de Execução do Windows e 'event' é um evento .NET regular.
  • CS1997: Como a função é um método assíncrono que retorna um valor, uma palavra-chave de retorno não deve ser seguida por uma expressão de objeto.
  • CS1998: Este método assíncrono não tem operadores 'await' e será executado de forma síncrona. Considere usar o operador 'await' para aguardar chamadas de API sem bloqueio, ou 'await Task.Run(...)' para fazer trabalho vinculado à CPU em um thread em segundo plano.
  • CS4014: Como essa chamada não é esperada, a execução do método atual continua antes que a chamada seja concluída. Considere aplicar o await operador ao resultado da chamada.
  • CS9123: O operador '&' não deve ser usado em parâmetros ou variáveis locais em métodos assíncronos.

Para escrever código assíncrono corretamente e evitar armadilhas comuns, siga estas práticas recomendadas. Para obter mais informações, consulte Programação assíncrona com async e await.

  • Sempre use await em chamadas para métodos assíncronos que retornam Task ou Task<TResult> (CS4014). Chamadas não esperadas podem levar a exceções perdidas e comportamento inesperado.
  • Não retorne um valor de métodos assíncronos que retornam Task (não genéricos); use Task<T> em vez disso (CS1997).
  • Inclua pelo menos um await operador em métodos assíncronos ou remova o async modificador (CS1998).
  • Remova a return instrução se o método deve retornar Task (CS1997, CS1998).
  • Altere o tipo de retorno do método para Task<T> retornar um valor (CS1997, CS1998).
  • Remova o async modificador e retorne a tarefa diretamente se não precisar da máquina de estado assíncrona (CS1997, CS1998).
  • Não use métodos assíncronos em árvores de expressão (CS1989). As árvores de expressão representam o código como dados e não suportam as transformações complexas da máquina de estado exigidas pelos métodos assíncronos.
  • Não marcar adicionar ou remover acessores numa interface ou evento WinRT como assíncrono (CS1991). Esta é uma restrição específica de plataforma para a interoperabilidade do Windows Runtime.
  • Evite usar o operador address-of (&) em expressões dentro de métodos assíncronos (CS9123). O alvo pode ser realocado na memória durante a suspensão, tornando o ponteiro inválido.