英語で読む

次の方法で共有


コンパイラ エラー CS1996

lock ステートメントの本体で待機することはできません

次の例では 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;
        }
    }
}

上記のコードでは、awaitlock ステートメント ブロック内にあるので、C# 13 でも同じエラーが発生します。

このエラーを解決するには

lock ステートメント ブロック内の非同期コードを信頼性の高い方法で実装するのは難しく、汎用的に実装するのはさらに難しくなります。 デッドロックが発生しやすいコードが生成されるのを避けるため、C# コンパイラではこれはサポートされていません。 lock ステートメント ブロックから非同期コードを外に出すことで、このエラーを修正できます。 次に例を示します。

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