Condividi tramite


Errore del compilatore CS1996

Non è possibile includere un elemento await nel corpo di un'istruzione lock

Esempio

L'esempio seguente genera l'errore CS1996:

public class C
{
    private readonly Dictionary<string, string> keyValuePairs = new();

    public async Task<string> ReplaceValueAsync(string key, HttpClient httpClient)
    {
        lock (keyValuePairs)
        {
            var newValue = await httpClient.GetStringAsync(string.Empty);
            if (keyValuePairs.ContainsKey(key)) keyValuePairs[key] = newValue;
            else keyValuePairs.Add(key, newValue);
            return newValue;
        }
    }
}

Il codice precedente genera lo stesso errore con C# 13, poiché await è nel blocco di istruzioni lock.

Per correggere l'errore

Il codice asincrono all'interno di un blocco di istruzioni lock è difficile da implementare in modo affidabile e ancora più difficile da implementare in senso generale. Il compilatore C# non supporta questa operazione per evitare di generare codice soggetto a deadlock. L'estrazione del codice asincrono dal blocco di istruzioni lock corregge questo errore. Ad esempio:

public class C
{
    private readonly Dictionary<string, string> keyValuePairs = new();

    public async Task<string> ReplaceValueAsync(string key, HttpClient httpClient)
    {
        var newValue = await httpClient.GetStringAsync(string.Empty);
        lock (keyValuePairs)
        {
            if (keyValuePairs.ContainsKey(key)) keyValuePairs[key] = newValue;
            else keyValuePairs.Add(key, newValue);
            return newValue;
        }
    }
}