锁定和简单缓存
我有以下代码。当部署到服务器,我得到例外,这个对象已经存在于字典。尽管如此,我做了双重锁定,同步并没有很好地发挥作用。实现这个最好的方法是什么?我怎样才能最好地锁定访问本节?我应该实现一个单例类并将方法放在那里?锁定和简单缓存
我应该锁定集合还是互斥锁?
NO我不是基于.NET 4
正如你所看到的,我想要做基于日期时间一个简单的缓存。
// within the class.
IDictionary<id, MyObj> _mydict = new Dictionary<string, MyObj>();
object mutex = new object;
//within some method comes the following
if (_mydict.TryGetValue(id, out myobj))
{
DateTime now = DateTime.Now;
DateTime expiry = myobj.Timestamp;
TimeSpan span = now.Subtract(expiry);
if (span.Minutes 0)
{
lock (mutex)
{
myobj= DataAccess.GetMyObj(id);
_mydict[id] = myobj;
}
return myobj;
}
else
{
return myobj;
}
}
else
{
lock (mutex)
{
if (_mydict.TryGetValue(id, out myobj))
{
return myobj;
}
else
{
lock (mutex)
{
myobj = DataAccess.GetMyObj(id);
_mydict[id] = myobj;
}
return myobj;
}
}
}
字典不是线程安全的,从阅读,你甚至称TryGetValue前应该锁定,基本上如果你使用的是字典只有一两件事可以一次触摸它
老兄,你为什么要锁定整本字典查找?那么在多线程环境中使用字典有什么意义呢?如果它像单身人士一样工作的话。??????? – DarthVader 2011-03-01 01:26:10
这篇文章有一个很好的解释为什么双重检查锁定不适用于Dictionary。请参阅http://*.com/questions/2624301/how-to-show-that-the-double-checked-lock-pattern-with-dictionarys-trygetvalue-is – rsbarro 2011-03-01 03:33:12
如果您使用.Net 4使用ConcurrentDictionary类应该是相当有帮助的。它会照顾你的锁定。
通常[System.Collections.Concurrent](http://msdn.microsoft.com/zh-cn/library/dd287108.aspx)命名空间有许多很酷的数据结构,并不是很多人使用它们。 :( – 2011-03-01 00:34:52
NO IM NOT ON .NET 4 – DarthVader 2011-03-01 00:36:26
应该_mydict [名称] = MyObj中;是_mydict [ID] = MyObj中;在第一个代码块应该_internetServiceProviderCache [ID] = MyObj中;?是_mydict [ID] – rsbarro 2011-03-01 00:59:18
只需使用ASP.Net缓存,而不是(你不需要将创建一个Web应用程序这个工作,只需添加一个参考System.Web
):
void get(string key)
{
return HttpRuntime.Cache[key];
}
void set(string key, object value, DateTime expires)
{
HttpRuntime.Cache.Insert(
key,
value,
null,
expires,
Cache.NoSlidingExpiration);
}
简单,方便,也意味着缓存现在也有ASP.Net缓存的其他所有功能(高速缓存大小的盖子,缓存的依赖等)
我同意,在System.Web命名空间中的ASP.NET缓存内置工作得很好,让你不必自己写所有这些东西。缓存应用程序块也工作得很好好。 – rsbarro 2011-03-01 01:11:43
我不能使用。 – DarthVader 2011-03-01 01:12:59
@ user177883为什么呢?因为2.0版本的.NET Framework的它一直一部分,是完全独立的比参考的System.Web其他的ASP.Net框架。 – Justin 2011-03-01 01:21:08
为什么不尝试使用列表,并插入即用类项目的值和插入该值的时间戳。然后,您可以搜索最新的时间戳和值,对结果列表进行排序,然后使用顶部项目。如果您认为合适,您可以将旧项目过期。
没有名单。字典。 – DarthVader 2011-03-01 01:30:28
正确的,使用字典限制你搜索一个简单的密钥。如果您使用列表_and_使用该值和时间戳进行搜索,则不必担心多次插入。你的问题就变成了如何使高速缓存中未被使用的旧条目到期。 – 2011-03-01 03:46:54
如若第二个到最后的代码行是'_myDict.Add(id,myobj)'? – 2011-03-01 01:10:28
它有关系吗?我得到“这个项目已经在集合中”,这就是我为什么这样做的原因。 – DarthVader 2011-03-01 01:22:26
如果我们看不到**完全**你在做什么,很难说出什么问题。 – 2011-03-01 02:20:11