Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo articolo illustra gli errori del compilatore seguenti:
-
CS1983: poiché si tratta di un metodo asincrono, l'espressione restituita deve essere di tipo '
T' anziché 'Task<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. - CS4001: Impossibile attendere l'espressione.
-
CS4003: '
await' non può essere usato come identificatore all'interno di un metodo asincrono o di un'espressione lambda. - CS4005: i metodi asincroni non possono avere parametri di tipo puntatore.
- CS4006: __arglist non è consentito nell'elenco dei parametri dei metodi asincroni.
-
CS4007: L'istanza del tipo non può essere conservata oltre il limite '
await' o 'yield'. -
CS4008: impossibile attendere '
void'. - CS4009: Un punto di ingresso che restituisce void o int non può essere asincrono.
- CS4010: impossibile convertire un'espressione asincrona in un tipo delegato. Un'espressione asincrona può restituire void, Task o Task<T>, nessuno dei quali è convertibile nel tipo.
-
CS4011: '
await' richiede che il tipo restituito di '{1}.GetAwaiter()' abbia i membri 'IsCompleted', 'OnCompleted' e 'GetResult' e implementi 'INotifyCompletion' o 'ICriticalNotifyCompletion'. - CS4012: i parametri di tipo non possono essere dichiarati in metodi asincroni o espressioni lambda asincrone.
-
CS4014: poiché questa chiamata non è attesa, l'esecuzione del metodo corrente continua prima del completamento della chiamata. Valutare la possibilità di applicare l'operatore
awaital risultato della chiamata. - CS4015: 'MethodImplOptions.Synchronized' non può essere applicato a un metodo asincrono.
- CS4016: Poiché si tratta di un metodo asincrono, l'espressione restituita deve essere di un tipo simile a Task anziché il tipo dichiarato.
- CS4027: Il tipo espressione non implementa il membro richiesto.
-
CS4028: '
await' richiede che il tipo disponga di un metodo 'GetAwaiter' appropriato. Manca una direttiva using per 'System'? - CS4029: impossibile restituire un'espressione di tipo 'void'.
- CS4030: l'attributo di sicurezza non può essere applicato a un metodo asincrono.
- CS4031: i metodi asincroni non sono consentiti in un'interfaccia, una classe o una struttura con l'attributo 'SecurityCritical' o 'SecuritySafeCritical'.
-
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'. -
CS4034: l'operatore '
await' può essere usato solo all'interno di un metodo asincrono. Valutare la possibilità di contrassegnare questo metodo con il modificatore "asincrono". - CS8031: Un'espressione lambda asincrona convertita in un delegato che restituisce un Task non può restituire un valore.
-
CS8100: l'operatore '
await' non può essere usato in un inizializzatore di variabile di script statico. - CS8177: I metodi asincroni non possono avere variabili locali per riferimento.
-
CS8178: un riferimento restituito da una chiamata al metodo non può essere mantenuto attraverso il limite '
await' o 'yield'. - CS8204: per il tipo da usare come AsyncMethodBuilder per la destinazione del tipo, la relativa proprietà Task deve restituire il tipo di destinazione anziché il tipo dichiarato.
-
CS8403: il metodo con un blocco iteratore deve essere '
async' per restituire IAsyncEnumerable<T>. - CS8411: l'istruzione foreach asincrona non può operare su variabili di tipo perché il tipo non contiene un'istanza pubblica o una definizione di estensione appropriata per il membro richiesto.
- CS8892: il metodo non verrà usato come punto di ingresso perché è stato trovato un punto di ingresso sincrono.
- CS8935: l'attributo AsyncMethodBuilder non è consentito nei metodi anonimi senza un tipo restituito esplicito.
- CS8940: Era previsto un tipo di ritorno generico simile a un'attività, ma il tipo trovato nell'attributo 'AsyncMethodBuilder' non è risultato adatto. Deve essere un tipo generico non vincolato di arità 1 e il tipo contenitore (se presente) deve essere non generico.
-
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'. -
CS4034: l'operatore '
await' può essere usato solo all'interno di un metodo asincrono. Valutare la possibilità di contrassegnare questo metodo con il modificatore "asincrono". -
CS8178: un riferimento restituito da questa chiamata non può essere mantenuto attraverso il limite '
await' o 'yield'. - CS8411: l'istruzione foreach asincrona non può operare su variabili di tipo perché il tipo non contiene un'istanza pubblica o una definizione di estensione appropriata per il membro richiesto.
- CS4001: Impossibile attendere l'espressione.
-
CS4003: '
await' non può essere usato come identificatore all'interno di un metodo asincrono o di un'espressione lambda. -
CS4007: l'istanza di tipo non può essere mantenuta attraverso il limite '
await' o 'yield'. -
CS4011: '
await' richiede che il tipo restituito di 'GetAwaiter()' disponga di membri appropriati di 'IsCompleted', 'OnCompleted' e 'GetResult' e implementa 'INotifyCompletion' o 'ICriticalNotifyCompletion'. - CS4027: il tipo non implementa il membro obbligatorio.
-
CS4028: '
await' richiede che il tipo disponga di un metodo 'GetAwaiter' appropriato. Manca una direttiva using per 'System'? -
CS8100: l'operatore '
await' non può essere usato in un inizializzatore di variabile di script statico.
Gli elementi seguenti illustrano come correggere ogni errore. Per altre informazioni sull'operatoreawait e sul modello awaiter, vedere Programmazione asincrona con async e await.
- Aggiungere il
asyncmodificatore al metodo o all'espressione lambda che contiene l'espressioneawait(CS1992, CS4032, CS4033, CS4034). Il compilatore richiede ilasyncmodificatore in modo che possa generare la macchina a stati che gestisce la sospensione asincrona e la ripresa. Le tre varianti di questo errore forniscono suggerimenti specifici del contesto per il tipo restituito corretto. - Spostare le espressioni
awaitdai blocchicatchquando si destina a C# 5 o versioni precedenti (CS1985). A partire da C# 6, il compilatore supportaawaitsia nei blocchicatchche nei blocchifinally. Questo errore non viene più generato in C# 6 e versioni successive. - Spostare le espressioni da blocchi di
await(lock). La sospensione asincrona mentre si mantiene un blocco comporta il rischio di deadlock. Il blocco viene mantenuto tra commutatori di thread in cui altro codice potrebbe essere in attesa dello stesso blocco. -
Ristrutturare le espressioni di query in modo che
awaitcompaia solo nella prima espressione di raccolta della clausola inizialefromo nell'espressione di raccolta di unajoinclausola (CS1995). Altre clausole di query si traducono in espressioni lambda che non supportano la sospensione asincrona. - Modificare il tipo dell'espressione attesa in modo che esponga un metodo accessibile
GetAwaiter()che segue il modello awaiter (CS1986, CS4028). Il tipo può implementare il modello direttamente o tramite un metodo di estensione. Se ilGetAwaitermetodo esiste ma manca unausingdirettiva perSystem, il compilatore genera il messaggio CS4028 più specifico anziché CS1986. - Verificare che il tipo awaiter restituito da
GetAwaiter()abbiaIsCompletedmembri ,OnCompletedeGetResulte implementi INotifyCompletion o ICriticalNotifyCompletion (CS4011, CS4027). L'espressioneawaitdipende da questi membri per controllare lo stato di completamento, registrare le continuazioni e recuperare i risultati. - Modificare il tipo restituito del metodo chiamato da
voida Task o Task<TResult> in modo che il risultato possa essere atteso (CS4008). Non è possibile attendere un metodo che restituiscevoidperché non esiste alcun oggetto task per monitorare il completamento o propagare le eccezioni. - Modificare l'espressione attesa in un tipo che supporta il modello awaiter (CS4001). I tipi come
int,stringe altri tipi predefiniti non hanno unGetAwaitermetodo e non possono essere attesi direttamente. - Archiviare il risultato di una chiamata al metodo che restituisce ref in una variabile locale prima di usare
await(CS8178). Un riferimento restituito da un metodo non può essere conservato attraverso unawaitconfine, perché la macchina a stati asincrona potrebbe sospendersi e riprendere su un thread o contesto diverso, invalidando il riferimento. - Implementare IAsyncEnumerable<T> nel tipo di raccolta o aggiungere un metodo accessibile
GetAsyncEnumeratorche restituisce un tipo con membriCurrenteMoveNextAsync(CS8411). L'istruzioneawait foreachrichiede che il tipo di raccolta segua il modello enumerabile asincrono. - Rinominare qualsiasi variabile o parametro locale denominato
awaitall'interno di un metodo o di un'espressioneasynclambda (CS4003). All'interno di contesti asincroni,awaitè una parola chiave contestuale e non può essere usata come identificatore. - Spostare l'espressione dall'inizializzatore
awaitdella variabile di script statica al corpo di un metodo (CS8100). Gli inizializzatori statici vengono eseguiti all'esterno di un contesto asincrono, quindiawaitnon sono disponibili in tale posizione. - Ristrutturare il codice in modo che non sia necessario mantenere le istanze
ref structoltre un confineawaitoyield(CS4007). La macchina async state archivia le variabili locali nell'heap eref structi tipi sono associati allo stack in base alla progettazione. Non possono essere spostate in modo sicuro nell'archivio heap tra punti di sospensione.
Requisiti di firma del metodo asincrono
-
CS1983: poiché si tratta di un metodo asincrono, l'espressione restituita deve essere di tipo 'T' anziché '
Task<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.
- CS8935: l'attributo AsyncMethodBuilder non è consentito nei metodi anonimi senza un tipo restituito esplicito.
- CS8940: è previsto un tipo restituito generico simile a 'Task', ma il tipo trovato nell'attributo 'AsyncMethodBuilder' non è adatto. Deve essere un tipo generico non vincolato di arità 1 e il tipo contenitore (se presente) deve essere non generico.
-
CS8403: il metodo con un blocco iteratore deve essere '
async' per restituire '{1}'. -
CS9330: '
MethodImplAttribute.Async' non può essere applicato manualmente ai metodi. Contrassegnare il metodo 'async'. - CS4005: i metodi asincroni non possono avere parametri di tipo puntatore.
- CS4006: __arglist non è consentito nell'elenco dei parametri dei metodi asincroni.
- CS4010: Impossibile convertire l'espressione lambda asincrona nel tipo delegato . Un'espressione lambda asincrona può restituire void, Task o Task<T>, nessuno dei quali è convertibile in un tipo restituito.
- CS4012: i parametri di tipo non possono essere dichiarati in metodi asincroni o espressioni lambda asincrone.
- CS4015: 'MethodImplOptions.Synchronized' non può essere applicato a un metodo asincrono.
- CS4016: Poiché si tratta di un metodo asincrono, l'espressione restituita deve essere di tipo Task anziché di tipo normale.
- CS8031: Un'espressione lambda asincrona convertita in un delegato che restituisce un Task non può restituire un valore.
- CS8204: per il tipo da usare come AsyncMethodBuilder per il tipo, la relativa proprietà Task deve restituire il tipo richiesto anziché il tipo dichiarato.
Gli elementi seguenti illustrano come correggere ogni errore. Per ulteriori informazioni sulle dichiarazioni di metodi asincroni, vedere il modificatore async e i tipi restituiti asincroni.
- Modificare l'espressione restituita in modo che corrisponda al tipo di risultato sottostante del metodo asincrono (CS1983, CS4016). Quando un metodo asincrono restituisce
Task<T>, l'istruzionereturndeve fornire un valore di tipoT, nonTask<T>, perché la macchina a stati generata dal compilatore esegue automaticamente il wrapping del valore in un'attività. CS1983 viene visualizzato quando il metodo restituisceTask<T>e l'espressione èT; CS4016 illustra il caso generale in cui il tipo di espressione restituito non corrisponde. - Rimuovere il
asyncmodificatore dai metodi che non hanno un corpo, ad esempio metodi astratti o dichiarazioni di metodi di interfaccia (CS1994). Ilasyncmodificatore richiede un corpo del metodo in modo che il compilatore possa generare l'implementazione della macchina a stati. - Modificare il tipo restituito di un punto di ingresso asincrono in Task o Task<TResult> (CS4009). A partire da C# 7.1, il
Mainmetodo può essereasync, ma deve restituireTaskoTask<int>-async voideasync intnon sono firme di punto di ingresso valide. - Rimuovere o rinominare un punto di ingresso quando il progetto contiene sia un metodo sincrono che un metodo asincrono
Main(CS8892). Il compilatore seleziona il punto di ingresso sincrono e genera questo avviso riguardo al candidato asincrono che ignora. - Aggiungere un tipo restituito esplicito all'espressione lambda prima di applicare l'attributo
[AsyncMethodBuilder](CS8935). Il compilatore non può risolvere il tipo di generatore per un metodo anonimo il cui tipo restituito viene dedotto, perché l'attributo deve essere associato a un tipo restituito specifico in fase di compilazione. - Modificare il tipo specificato nell'attributo
[AsyncMethodBuilder]in un tipo generico non associato di arity one, ad esempioMyTaskMethodBuilder<>anzichéMyTaskMethodBuilder<T>un tipo non generico (CS8940). Il tipo contenitore del costruttore, se presente, deve anche essere non generico. Il compilatore richiede questa forma affinché possa costruire il costruttore per qualsiasi tipo di ritorno concreto task-like. - Sostituire l'attributo manuale
[MethodImpl(MethodImplOptions.Async)]con laasyncparola chiave nella dichiarazione del metodo (CS9330). IlMethodImplOptions.Asyncflag è riservato per l'uso del runtime interno e non può essere applicato direttamente nel codice utente. - Aggiungere il
asyncmodificatore ai metodi che contengono blocchi iteratori e restituire IAsyncEnumerable<T> o IAsyncEnumerator<T> (CS8403). Senza ilasyncmodificatore, il compilatore considera il metodo come iteratore sincrono e non può generare la macchina a stati per il flusso asincrono. - Rimuovere i parametri di tipo puntatore dai metodi asincroni (CS4005). I puntatori fanno riferimento a percorsi di memoria fissa che non possono essere mantenuti in modo sicuro in punti di sospensione asincroni in cui l'esecuzione potrebbe riprendere in un thread diverso.
- Rimuovere
__arglistdagli elenchi di parametri del metodo asincrono (CS4006). Gli elenchi di argomenti a lunghezza variabile dipendono da convenzioni di chiamata basate su stack, che sono incompatibili con la macchina a stati asincrona allocata dall'heap. - Rimuovere
refparametri ,inooute parametri diref structtipi come Span<T> o ReadOnlySpan<T>, da metodi asincroni o espressioni lambda asincrone (CS4012). Questi tipi di parametro sono associati allo stack e non possono essere acquisiti in modo sicuro nella chiusura della macchina a stato asincrona allocata nell'heap. - Modificare il tipo delegato di destinazione in modo che corrisponda al tipo restituito dell'espressione lambda asincrona (CS4010). Un'espressione lambda asincrona può restituire
void, Tasko Task<TResult>e il compilatore non può convertirli in tipi delegati arbitrari che prevedono tipi restituiti diversi. - Rimuovere l'espressione
returnda un'espressione lambda asincrona assegnata a un delegato non genericoTasko modificare il tipo delegato inFunc<Task<T>>in modo che l'espressione lambda possa restituire un valore (CS8031). Un delegato che restituisce non genericamenteTaskrappresenta un'operazione asincrona senza risultato, quindi la restituzione di un valore risulta in un errore di corrispondenza di tipo. - Rimuovere l'attributo
[MethodImpl(MethodImplOptions.Synchronized)]dai metodi asincroni (CS4015). L'opzioneSynchronizedacquisisce un blocco per l'intera esecuzione del metodo, ma un metodo asincrono sospende e riprende potenzialmente su thread diversi, rendendo la semantica del blocco non definita. - Correggere il tipo personalizzato
AsyncMethodBuilderin modo che la relativaTaskproprietà restituisca lo stesso tipo del tipo restituito dichiarato dal metodo asincrono (CS8204). Il compilatore usa la proprietà delTaskgeneratore per ottenere l'oggetto attività finale, pertanto un'incompatibilità di tipo impedisce il corretto funzionamento della macchina degli stati.
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
awaital risultato della chiamata. - CS8177: I metodi asincroni non possono avere variabili locali per riferimento.
-
CS9123: l'operatore '
&' non deve essere usato nei parametri o nelle variabili locali nei metodi asincroni. - CS4029: impossibile restituire un'espressione di tipo 'void'.
- CS4030: l'attributo di sicurezza non può essere applicato a un metodo asincrono.
- CS4031: i metodi asincroni non sono consentiti in un'interfaccia, una classe o una struttura con l'attributo 'SecurityCritical' o 'SecuritySafeCritical'.
Gli elementi seguenti illustrano come correggere ogni errore. Per altre informazioni, vedere Programmazione asincrona con async e await e l'operatoreawait .
- Aggiungere l'operatore
awaita ogni chiamata che restituisce Task o Task<TResult>oppure rimuovere in modo esplicito il risultato con_ =se il comportamento fire-and-forget è veramente previsto (CS4014). Senzaawait, qualsiasi eccezione generata dall'operazione asincrona viene persa automaticamente e il metodo chiamante continua l'esecuzione prima del completamento dell'operazione, che può causare bug di ordinamento e correttezza sottili. - Rimuovere l'espressione
returnda un metodo asincrono il cui tipo restituito èTask(non generico) o modificare il tipo restituito inTask<T>quando il metodo deve restituire un valore (CS1997). In un metodo asincrono che restituisceTask, il compilatore genera il wrapper del compito - restituire un valore provoca una discordanza di tipo, perché la firma del metodo non promette alcun risultato. - Aggiungi almeno un'espressione
awaital corpo del metodo o rimuovi il modificatoreasynce restituisci direttamente l'attività (CS1998). Unasyncmetodo senzaawaitespressioni viene eseguito completamente in modo sincrono, che comporta un sovraccarico della macchina a stati finiti non necessario. Se il metodo avvolge intenzionalmente un'operazione sincrona, la rimozione diasynce la restituzione dell'oggetto attività elimina esplicitamente tale overhead. - Riscrivere l'espressione lambda in modo che non venga usata
asyncquando viene assegnata a un tipo di albero delle espressioni comeExpression<Func<...>>(CS1989). Gli alberi delle espressioni rappresentano il codice come strutture di dati che il compilatore può analizzare o tradurre, ma la macchina a stati complessa cheasyncproduce non può essere acquisita in un albero delle espressioni. - Modificare l'implementazione dell'evento in modo che sia la dichiarazione di interfaccia che la classe di implementazione accettino se l'evento usa la semantica di Windows Runtime o la normale semantica .NET (CS1991). Questo errore si applica agli scenari di interoperabilità di Windows Runtime in cui un evento WinRT non può essere implementato come normale evento .NET o viceversa.
- Rimuovere l'operatore address-of (
&) dalle espressioni che fanno riferimento a parametri o variabili locali all'interno di metodi asincroni (CS9123). La macchina a stati asincrona potrebbe rilocare le variabili catturate nell'heap durante la sospensione, il che invaliderebbe qualsiasi puntatore ottenuto tramite l'indirizzo di. - Rimuovere le variabili locali per riferimento dai metodi asincroni o assicurarsi che non si estendono su un
awaitlimite (CS8177). La macchina a stati asincrona acquisisce le variabili locali nelle closures allocate sul heap e i riferimenti alle posizioni nello stack non possono essere conservati in modo sicuro attraverso i punti di sospensione. In C# 13 e versioni successive, le variabili localirefsono consentite nei metodi asincroni purché non si estenda su unawaitlimite e questo errore non viene generato. - Rimuovere l'istruzione
returnche restituisce il risultato di unvoidmetodo -returning oppure modificare il metodo chiamato per restituire un valore (CS4029). Non è possibile usarereturn SomeVoidMethod();perchévoidnon è un tipo che può essere restituito come valore. Rimuovere lareturnparola chiave e chiamare il metodo come istruzione autonoma oppure modificare la firma del metodo chiamato per restituire un tipo concreto. - Rimuovere attributi di sicurezza come
[SecurityCritical]o[SecuritySafeCritical]da metodi asincroni (CS4030) o rimuovere ilasyncmodificatore dai metodi nei tipi contrassegnati con questi attributi (CS4031). Le annotazioni di sicurezza per l'accesso al codice si applicano al metodo dichiarante, ma la macchina a stati asincrona generata dal compilatore viene eseguita in un contesto separato in cui tali annotazioni di sicurezza non possono essere applicate.