Compartilhar via


Erro do compilador CS1996

Não é possível aguardar no corpo de uma instrução lock

Exemplo

O exemplo a seguir gera o erro 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;
        }
    }
}

O código anterior produz o mesmo erro com C# 13, já que o await está no bloco de instruções lock.

Para corrigir este erro

O código assíncrono dentro de um bloco de instrução lock é difícil de implementar de maneira confiável e ainda mais difícil de implementar em um sentido geral. O compilador C# não permite fazer isso para evitar emitir código propenso a deadlocks. Extrair o código assíncrono do bloco de instruções lock corrige esse erro. Por exemplo:

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