Compartilhar via


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

Este artigo aborda os seguintes avisos 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 esperar em uma cláusula catch.
  • 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 Windows Runtime 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 'assíncrono'.
  • CS1994: O modificador 'async' só pode ser usado em métodos que têm 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 é possível aguardar no corpo de uma instruçã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: esse método assíncrono não tem operadores 'await' e será executado de forma síncrona. Considere usar o operador 'await' para aguardar chamadas à API sem bloqueio ou 'await Task.Run(...)' para fazer o trabalho associado à CPU em um thread em segundo plano.
  • CS4008: Não é possível aguardar 'void'.
  • CS4009: um ponto de entrada nulo ou int retornando não pode ser assíncrono.
  • CS4014: como essa chamada não é aguardada, a execução do método atual continua antes da conclusão da chamada. Considere aplicar o await operador ao resultado da chamada.
  • CS4032: o operador 'await' só pode ser usado em um método assíncrono. Considere marcar esse método com o modificador 'assíncrono' e alterar seu tipo de retorno para 'Task<T>'.
  • CS4033: o operador 'await' só pode ser usado em 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 aos métodos. Marque o método 'async'.

Aguardar requisitos de expressão

  • CS1985: Não é possível aguardar em uma cláusula catch.
  • 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 é possível aguardar no corpo de uma instrução de bloqueio.
  • CS4008: Não é possível aguardar 'void'.
  • CS4032: o operador 'await' só pode ser usado em 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 em 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 use await nas cláusulas catch (CS1985). Embora você possa usar await em blocos try e finally (em C# 6 e posterior), os blocos catch apresentam desafios especiais com o tratamento de exceções e o fluxo de execução.
  • Não use await dentro de blocos de instrução lock (CS1996). O compilador não dá suporte a isso para evitar emitir código propenso a deadlocks.
  • Use await apenas em locais específicos dentro de expressões de consulta (CS1995): dentro da expressão de coleção inicial na primeira cláusula from ou dentro da expressão de coleção de uma cláusula join.
  • 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 de aguardador (CS1986).
  • Não se aplique await a expressões de 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 têm um corpo.
  • CS4009: Um ponto de entrada que retorna void 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 aos métodos. Marque o método 'async'.

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

  • Retornar um dos tipos válidos: void, Task, Task<T>, um tipo de tarefa, IAsyncEnumerable<T> ou IAsyncEnumerator<T> (CS1983).
  • Use o modificador async somente 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 no ponto de entrada em versões anteriores (CS4009).
  • Remova 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 Windows Runtime 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: esse método assíncrono não tem operadores 'await' e será executado de forma síncrona. Considere usar o operador 'await' para aguardar chamadas à API sem bloqueio ou 'await Task.Run(...)' para fazer o trabalho associado à CPU em um thread em segundo plano.
  • CS4014: como essa chamada não é aguardada, a execução do método atual continua antes da conclusão da chamada. 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 o 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 aguarde chamadas para métodos assíncronos que retornam Task ou Task<TResult> (CS4014). Chamadas não aguardadas 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 você não precisar do computador de estado assíncrono (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 dão suporte às transformações complexas da máquina de estado exigidas por métodos assíncronos.
  • Não marque adicionar ou remover acessadores em uma interface ou evento WinRT como assíncrono (CS1991). Essa é uma restrição específica da plataforma para interoperabilidade do Windows Runtime.
  • Evite usar o operador de endereço (&) 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.