Compartir a través de


Error del compilador CS1996

No se puede usar await en el cuerpo de una instrucción de bloqueo.

Ejemplo

En el ejemplo siguiente se genera el error 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;
        }
    }
}

El código anterior genera el mismo error con C# 13, ya que await está en el bloque de instrucciones lock.

Para corregir este error

El código asincrónico dentro de un bloque de instrucciones lock es difícil de implementar de forma confiable e incluso más difícil de implementar en un sentido general. El compilador de C# no admite hacerlo para evitar emitir código propenso a interbloqueos. Al extraer el código asincrónico del bloque de instrucciones lock, se corrige este error. Por ejemplo:

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;
        }
    }
}