Condividi tramite


Risolvere gli errori e gli avvisi nei metodi asincroni usando l'operatore await

Questo articolo illustra gli errori del compilatore seguenti:

  • CS1983: poiché si tratta di un metodo asincrono, l'espressione restituita deve essere di tipo 'Task<T>' anziché 'T'.
  • CS1985: Non si può attendere in una clausola catch.
  • CS1986: 'await' richiede che il tipo disponga di un metodo 'GetAwaiter' appropriato.
  • CS1989: le espressioni lambda asincrone non possono essere convertite in alberi delle espressioni.
  • CS1991: 'Type' non può implementare 'event' perché si tratta di un evento di Windows Runtime e 'event' è un normale evento .NET.
  • CS1992: l'operatore 'await' può essere usato solo quando è contenuto all'interno di un metodo o di un'espressione lambda contrassegnata con il modificatore "asincrono".
  • CS1994: il modificatore 'async' può essere usato solo nei metodi con un corpo.
  • CS1995: l'operatore 'await' può essere usato solo in un'espressione di query all'interno della prima espressione di raccolta della clausola 'from' iniziale o all'interno dell'espressione di raccolta di una clausola 'join'.
  • CS1996: Impossibile usare 'await' nel corpo di un'istruzione lock.
  • CS1997: poiché la funzione è un metodo asincrono che restituisce un valore, una parola chiave return non deve essere seguita da un'espressione oggetto.
  • CS1998: questo metodo asincrono non dispone di operatori 'await' e verrà eseguito in modo sincrono. Prendere in considerazione l'uso dell'operatore 'await' per attendere le chiamate API non bloccate o 'await Task.Run(...)' per eseguire operazioni associate alla CPU in un thread in background.
  • CS4008: impossibile attendere 'void'.
  • CS4009: Un punto di ingresso che restituisce void o int non può essere asincrono.
  • CS4014: poiché questa chiamata non è attesa, l'esecuzione del metodo corrente continua prima del completamento della chiamata. Valutare la possibilità di applicare l'operatore await al risultato della chiamata.
  • CS4032: l'operatore 'await' può essere usato solo all'interno di un metodo asincrono. Valutare la possibilità di contrassegnare questo metodo con il modificatore "asincrono" e di modificarne il tipo restituito in "Task<T>".
  • CS4033: l'operatore 'await' può essere usato solo all'interno di un metodo asincrono. Valutare la possibilità di contrassegnare questo metodo con il modificatore 'async' e di modificarne il tipo restituito in 'Task'.
  • CS8892: il metodo non verrà usato come punto di ingresso perché è stato trovato un punto di ingresso sincrono.
  • CS9123: l'operatore '&' non deve essere usato nei parametri o nelle variabili locali nei metodi asincroni.
  • CS9330: 'MethodImplAttribute.Async' non può essere applicato manualmente ai metodi. Contrassegnare il metodo 'async'.

Requisiti dell'espressione Await

  • CS1985: Impossibile utilizzare 'await' in una clausola catch.
  • CS1986: 'await' richiede che il tipo disponga di un metodo 'GetAwaiter' appropriato.
  • CS1992: l'operatore 'await' può essere usato solo quando è contenuto all'interno di un metodo o di un'espressione lambda contrassegnata con il modificatore 'async'.
  • CS1995: l'operatore 'await' può essere usato solo in un'espressione di query all'interno della prima espressione di raccolta della clausola 'from' iniziale o all'interno dell'espressione di raccolta di una clausola 'join'.
  • CS1996: Non è possibile usare 'await' nel corpo di un'istruzione di blocco (lock statement).
  • CS4008: impossibile attendere 'void'.
  • CS4032: l'operatore 'await' può essere usato solo all'interno di un metodo asincrono. Valutare la possibilità di contrassegnare questo metodo con il modificatore 'async' e di modificarne il tipo restituito in 'Task<T>'.
  • CS4033: l'operatore 'await' può essere usato solo all'interno di un metodo asincrono. Valutare la possibilità di contrassegnare questo metodo con il modificatore 'async' e di modificarne il tipo restituito in 'Task'.

Per usare correttamente l'operatore await , seguire queste regole. Per altre informazioni, vedere Programmazione asincrona con async e await.

  • Non usare await nelle clausole catch (CS1985). Sebbene sia possibile usare await nei blocchi try e nei blocchi finally (in C# 6 e versioni successive), i blocchi catch comportano sfide particolari nella gestione delle eccezioni e nel flusso di controllo.
  • Non usare await dentro blocchi di istruzione lock (CS1996). Il compilatore non supporta questo problema per evitare di generare codice soggetto a deadlock.
  • Usare await solo in posizioni specifiche all'interno di espressioni di query (CS1995): all'interno della prima espressione di collezione della clausola iniziale from o all'interno dell'espressione di collezione di una clausola join.
  • Contrassegnare metodi o espressioni lambda con il async modificatore prima di usare await (CS1992, CS4032, CS4033).
  • Verificare che i tipi attesi abbiano un metodo accessibile GetAwaiter che restituisce un tipo awaiter (CS1986).
  • Non applicare await alle espressioni di tipo void (CS4008).
  • Modificare il tipo restituito in Task per i metodi che non restituiscono un valore o Task<T> per i metodi che restituiscono un valore.

Requisiti di firma del metodo asincrono

  • CS1983: poiché si tratta di un metodo asincrono, l'espressione restituita deve essere di tipo 'Task<T>' anziché 'T'.
  • CS1994: il modificatore 'async' può essere usato solo nei metodi con un corpo.
  • CS4009: Un punto di ingresso che restituisce void o int non può essere asincrono.
  • CS8892: il metodo non verrà usato come punto di ingresso perché è stato trovato un punto di ingresso sincrono.
  • CS9330: 'MethodImplAttribute.Async' non può essere applicato manualmente ai metodi. Contrassegnare il metodo 'async'.

Per dichiarare correttamente i metodi asincroni, seguire questi requisiti di firma. Per altre informazioni, vedere Valori restituiti principali asincroni.

  • Restituisce uno dei tipi validi: void, Task, Task<T>, un tipo simile a un'attività, IAsyncEnumerable<T>o IAsyncEnumerator<T> (CS1983).
  • Usare il async modificatore solo sui metodi con un corpo (CS1994). Rimuovere il async modificatore sui metodi astratti nelle interfacce o nelle classi.
  • Eseguire l'aggiornamento a C# 7.1 o versione successiva per utilizzare async nel punto di ingresso Main, oppure evitare di usare async nei punti di ingresso nelle versioni precedenti (CS4009).
  • Rimuovere i punti di ingresso sincroni se sono presenti sia punti di ingresso sincroni che asincroni (CS8892).
  • Usare la async parola chiave anziché applicare MethodImplAttribute.Async manualmente (CS9330).

Pratiche asincrone

  • CS1989: le espressioni lambda asincrone non possono essere convertite in alberi delle espressioni.
  • CS1991: 'Type' non può implementare 'event' perché si tratta di un evento di Windows Runtime e 'event' è un normale evento .NET.
  • CS1997: poiché la funzione è un metodo asincrono che restituisce un valore, una parola chiave return non deve essere seguita da un'espressione oggetto.
  • CS1998: questo metodo asincrono non dispone di operatori 'await' e verrà eseguito in modo sincrono. Prendere in considerazione l'uso dell'operatore 'await' per attendere le chiamate API non bloccate o 'await Task.Run(...)' per eseguire operazioni associate alla CPU in un thread in background.
  • CS4014: poiché questa chiamata non è attesa, l'esecuzione del metodo corrente continua prima del completamento della chiamata. Valutare la possibilità di applicare l'operatore await al risultato della chiamata.
  • CS9123: l'operatore '&' non deve essere usato nei parametri o nelle variabili locali nei metodi asincroni.

Per scrivere correttamente codice asincrono ed evitare problemi comuni, seguire queste procedure consigliate. Per altre informazioni, vedere Programmazione asincrona con async e await.

  • Utilizzare sempre await per le chiamate a metodi asincroni che restituiscono Task o Task<TResult> (CS4014). Le chiamate non attese possono causare eccezioni perse e comportamenti imprevisti.
  • Non restituire un valore da metodi asincroni che restituiscono Task (non generico); usare Task<T> invece (CS1997).
  • Includere almeno un await operatore nei metodi asincroni o rimuovere il async modificatore (CS1998).
  • Rimuovere l'istruzione return se il metodo deve restituire Task (CS1997, CS1998).
  • Modificare il tipo restituito del metodo in Task<T> per restituire un valore (CS1997, CS1998).
  • Rimuovi il async modificatore e restituisci direttamente l'attività se non hai bisogno della macchina a stati asincroni (CS1997, CS1998).
  • Non usare metodi asincroni negli alberi delle espressioni (CS1989). Gli alberi delle espressioni rappresentano il codice come dati e non supportano le trasformazioni complesse della macchina a stati richieste dai metodi asincroni.
  • Non contrassegnare l'aggiunta o la rimozione di funzioni di accesso in un'interfaccia o in un evento WinRT come asincrono (CS1991). Si tratta di una restrizione specifica della piattaforma per l'interoperabilità di Windows Runtime.
  • Evitare di usare l'operatore address-of (&) nelle espressioni all'interno di metodi asincroni (CS9123). Il puntatore potrebbe diventare non valido se l'oggetto target viene spostato nella memoria durante la sospensione.