锁定和简单缓存
我有以下代码。当部署到服务器时,我收到异常,该对象已存在于字典中。即使我做了双重锁定,同步效果也不太好。实现这一点的最佳方法是什么?我怎样才能最好地锁定对此部分的访问?我应该实现一个单例类并将方法放在其中吗?
我应该锁定集合还是互斥锁?
不,我不在.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;
}
}
}
I have the following code. When deployed to a server, i m getting exception that , this object already exists in the dictionary. Even though , i did double locking, synchrony didnt work quite well. What s the best way to implement this? How can i best lock access to this section? Should i implement a singleton class and place the methods in there?
Should i lock the collection or mutex?
NO I M NOT ON .NET 4
As you can see, i m trying to do a simple cache based on datetime.
// 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;
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
字典的读取不是线程安全的,您应该在调用 TryGetValue 之前锁定,基本上,如果您使用字典,一次只有一件事可以触及它
Dictionary isn't threadsafe to read from, you should lock before even calling TryGetValue, basically if you are using a Dictionary only one thing can touch it at a time
如果您使用 .Net 4,使用 ConcurrentDictionary 类应该非常有帮助。它会为您处理锁定问题。
If you are using .Net 4 using the ConcurrentDictionary class should be quite helpful. It will take care of the locking for you.
只需使用 ASP.Net 缓存即可(您无需为此创建 Web 应用程序,只需添加对
System.Web
的引用):简单、容易,也意味着您的缓存现在还具有 ASP.Net 缓存的所有其他功能(缓存大小上限、缓存依赖项等...)
Just use ASP.Net caching instead (you don't need to be creating a web application for this to work, just add a reference to
System.Web
):Simple, easy and also means that your cache now also has all the other features of the ASP.Net cache (A cap on cache size, caching dependencies etc...)
为什么不尝试使用列表,并插入一个项目,该项目是一个包含您的值和插入该值的时间戳的类。然后,您可以搜索最新的时间戳和值,对结果列表进行排序,并使用顶部项目。然后,您可以根据需要使旧项目过期。
Why not try using a list, and insert an item that is a class with your value and the timestamp that you inserted the value. Then you can search for the latest timestamp and value, order the resulted list, and use the top item. You can then expire the old items as you see fit.