1

私の ASP.NET Web アプリケーションでは、ページへのすべての要求がこの共通の静的キャッシュ クラスにアクセスします。(したがって、スレッドセーフでなければなりません)

以下に実装されている Cache クラスの Refresh メソッドを呼び出して、このキャッシュを更新しても安全ですか。それとも、同期の問題が発生しますか?

    static class Cache
    {
        static Dictionary<string, string> cachedCodeNames;
        static readonly object sync = new object();

        public static string GetName(string code)
        {
            return CodeNames[code];
        }

        public static void Refresh()
        {
            cachedCodeNames = null;
        }

        static Dictionary<string, string> CodeNames
        {
            get
            {
                if (cachedCodeNames == null)
                {
                    lock (sync)
                    {
                        if (cachedCodeNames == null)
                        {
                            cachedCodeNames = WebServiceManager.GetCodeNameCache();
                        }
                    }
                }
                return cachedCodeNames;
            }
        }
    }

    static class WebServiceManager
    {
        internal static Dictionary<string, string> GetCodeNameCache()
        {
            throw new NotImplementedException();
        }
    }
4

1 に答える 1

0

ここには確かに競合状態があります。1 つのスレッドが から抜け出し、lockその時点で別のスレッドが を呼び出す (そして完了する)Refresh場合、最初のスレッドは から戻りnullますCodeNamesCodeNamesが内部から読み取られていた場合GetName、これはすぐにNullReferenceException.

これを防ぐには、で保護するか、次のように書き換える必要がRefreshありますlock(sync)CodeNames

lock (sync)
{
    if (cachedCodeNames == null)
    {
        var codeNames = WebServiceManager.GetCodeNameCache();
        cachedCodeNames = codeNames;
        return codeNames;
    }
}

もちろん、この場合、この一見無意味な儀式が実際には重要な機能であることを明確にするために、大量のコメントを適用する必要があります。

于 2013-02-25T12:05:28.483 に答える