静态字典高速缓存的.NET线程安全性

时间:2013-02-25 12:00:59

标签: .net multithreading dictionary thread-safety

在我的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();
        }
    }

1 个答案:

答案 0 :(得分:0)

这里肯定存在竞争条件。如果一个线程刚刚退出lock并且此时另一个线程调用(并完成)Refresh,则第一个线程将从null返回CodeNames。如果从CodeNames内部读取GetName,则会立即生成NullReferenceException

为防止出现这种情况,您需要使用Refresh保护lock(sync)或像这样重写CodeNames

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

当然,在这种情况下,你应该申请大量的评论,以明确这个看似毫无意义的仪式实际上是一个重要的特征。