静态字典缓存的.NET线程安全 [英] .NET Thread Safety for Static Dictionary Cache
问题描述
在我的ASP.NET Web应用程序中,对页面的所有请求都访问此公共静态缓存类. (因此它必须是线程安全的)
In my ASP.NET Web application, all the requests to pages access this common static cache class. (So it has to be thread safe)
通过调用Cache类的Refresh方法(如下所述)来刷新此缓存是否安全. 还是会导致同步问题?
Is it safe to refresh this cache by calling the Refresh method of Cache class as implemented below. Or it causes sync problems?
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();
}
}
推荐答案
这里肯定存在竞争条件.如果一个线程刚刚退出lock
,然后另一个线程调用(并完成)Refresh
,则第一个线程将从CodeNames
返回null
.如果从GetName
内部读取了CodeNames
,则将立即生成NullReferenceException
.
There's certainly a race condition here. If one thread has just stepped out of the lock
and at that point another thread calls (and completes) Refresh
, the first thread is going to return null
from CodeNames
. If CodeNames
was being read from inside GetName
, this will immediately result in a NullReferenceException
.
为防止这种情况,您需要使用lock(sync)
保护Refresh
或像这样重写CodeNames
:
To prevent this, you 'd need to either protect Refresh
with a lock(sync)
or rewrite CodeNames
like this:
lock (sync)
{
if (cachedCodeNames == null)
{
var codeNames = WebServiceManager.GetCodeNameCache();
cachedCodeNames = codeNames;
return codeNames;
}
}
当然,在这种情况下,您应该进行大量评论,以表明这种看似毫无意义的仪式实际上是一项重要功能.
Of course in this case you should apply generous amounts of comments to make clear that this seemingly pointless ritual is in fact an important feature.
这篇关于静态字典缓存的.NET线程安全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!