CA2007: Non attendere direttamente un'attività
Proprietà | valore |
---|---|
ID regola | CA2007 |
Title | Non attendere direttamente un'attività |
Categoria | Affidabilità |
La correzione causa un'interruzione o meno | Non causa un'interruzione |
Abilitato per impostazione predefinita in .NET 9 | No |
Causa
Un metodo asincrono attende direttamente un oggetto Task .
Descrizione regola
Quando un metodo asincrono attende direttamente una Task continuazione, in genere si verifica nello stesso thread che ha creato l'attività, a seconda del contesto asincrono. Questo comportamento può essere costoso in termini di prestazioni e può comportare un deadlock nel thread dell'interfaccia utente. Valutare la possibilità di chiamare Task.ConfigureAwait(Boolean) per segnalare l'intenzione di continuare.
Come correggere le violazioni
Per correggere le violazioni, chiamare ConfigureAwait sull'oggetto atteso Task. È possibile passare o true
false
per il continueOnCapturedContext
parametro .
La chiamata
ConfigureAwait(true)
all'attività ha lo stesso comportamento di non chiamare ConfigureAwaitin modo esplicito . Chiamando in modo esplicito questo metodo, si comunica ai lettori che si vuole intenzionalmente eseguire la continuazione nel contesto di sincronizzazione originale.Chiamare
ConfigureAwait(false)
sull'attività per pianificare le continuazioni al pool di thread, evitando così un deadlock nel thread dell'interfaccia utente. Il passaggiofalse
è un'opzione valida per le librerie indipendenti dall'app.
Esempio
Il frammento di codice seguente genera l'avviso:
public async Task Execute()
{
Task task = null;
await task;
}
Per correggere la violazione, chiamare ConfigureAwait sul atteso Task:
public async Task Execute()
{
Task task = null;
await task.ConfigureAwait(false);
}
Quando eliminare gli avvisi
Questo avviso è destinato alle librerie, in cui il codice può essere eseguito in ambienti arbitrari e in cui il codice non deve fare ipotesi sull'ambiente o su come il chiamante del metodo potrebbe richiamare o attendere. In genere è opportuno eliminare completamente l'avviso per i progetti che rappresentano il codice dell'applicazione anziché il codice della libreria; Infatti, l'esecuzione di questo analizzatore nel codice dell'applicazione (ad esempio, i gestori eventi click del pulsante in un progetto WinForms o WPF) potrebbe causare l'esecuzione di azioni errate.
È possibile eliminare questo avviso in qualsiasi situazione in cui la continuazione deve essere pianificata di nuovo nel contesto originale o in cui non esiste un contesto di questo tipo. Ad esempio, quando si scrive codice in un gestore eventi click di un pulsante in un'applicazione WinForms o WPF, in generale la continuazione da un await deve essere eseguita nel thread dell'interfaccia utente e quindi il comportamento predefinito di pianificazione della continuazione nel contesto di origine è auspicabile. Come altro esempio, quando si scrive codice in un'applicazione ASP.NET Core, per impostazione predefinita non esiste o SynchronizationContext TaskScheduler, per cui un ConfigureAwait
oggetto non modifica effettivamente alcun comportamento.
Eliminare un avviso
Se si vuole eliminare una singola violazione, aggiungere direttive del preprocessore al file di origine per disabilitare e quindi riabilitare la regola.
#pragma warning disable CA2007
// The code that's violating the rule is on this line.
#pragma warning restore CA2007
Per disabilitare la regola per un file, una cartella o un progetto, impostarne la gravità none
su nel file di configurazione.
[*.{cs,vb}]
dotnet_diagnostic.CA2007.severity = none
Per altre informazioni, vedere Come eliminare gli avvisi di analisi del codice.
Configurare il codice da analizzare
Usare le opzioni seguenti per configurare le parti della codebase in cui eseguire questa regola.
È possibile configurare tutte queste opzioni solo per questa regola, per tutte le regole a cui si applica o per tutte le regole in questa categoria (affidabilità) a cui si applica. Per altre informazioni, vedere Opzioni di configurazione delle regole di qualità del codice.
Escludere i metodi async void
È possibile configurare se si desidera escludere metodi asincroni che non restituiscono un valore da questa regola. Per escludere questi tipi di metodi, aggiungere la coppia chiave-valore seguente a un file con estensione editorconfig nel progetto:
# Package version 2.9.0 and later
dotnet_code_quality.CA2007.exclude_async_void_methods = true
# Package version 2.6.3 and earlier
dotnet_code_quality.CA2007.skip_async_void_methods = true
Tipo di output
È anche possibile configurare i tipi di assembly di output a cui applicare questa regola. Ad esempio, per applicare questa regola solo al codice che produce un'applicazione console o una libreria collegata dinamicamente (ovvero, non un'app dell'interfaccia utente), aggiungere la coppia chiave-valore seguente a un file con estensione editorconfig nel progetto:
dotnet_code_quality.CA2007.output_kind = ConsoleApplication, DynamicallyLinkedLibrary