C# 锁定和简单缓存
我有以下代码。当部署到服务器时,我得到一个异常,这个对象已经存在于字典中。尽管我做了双重锁定,但同步并没有很好地工作。实现这一点的最佳方式是什么?我如何才能最好地锁定此分区的访问权限?我应该实现一个单例类并将方法放在其中吗 我应该锁定集合还是互斥锁 不,我不在.NET 4上 如您所见,我正在尝试基于datetime进行一个简单的缓存C# 锁定和简单缓存,c#,.net,iis,collections,locking,C#,.net,Iis,Collections,Locking,我有以下代码。当部署到服务器时,我得到一个异常,这个对象已经存在于字典中。尽管我做了双重锁定,但同步并没有很好地工作。实现这一点的最佳方式是什么?我如何才能最好地锁定此分区的访问权限?我应该实现一个单例类并将方法放在其中吗 我应该锁定集合还是互斥锁 不,我不在.NET 4上 如您所见,我正在尝试基于datetime进行一个简单的缓存 // within the class. IDictionary<id, MyObj> _mydict = new
// 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;
}
}
}
//在类中。
IDictionary_mydict=新字典();
对象互斥=新对象;
//在某些方法中会出现以下情况
if(_mydict.TryGetValue(id,out myobj))
{
DateTime now=DateTime.now;
DateTime expiration=myobj.Timestamp;
TimeSpan=now.Subtract(到期);
如果(span.0分钟)
{
锁(互斥)
{
myobj=DataAccess.GetMyObj(id);
_mydict[id]=myobj;
}
返回myobj;
}
其他的
{
返回myobj;
}
}
其他的
{
锁(互斥)
{
if(_mydict.TryGetValue(id,out myobj))
{
返回myobj;
}
其他的
{
锁(互斥)
{
myobj=DataAccess.GetMyObj(id);
_mydict[id]=myobj;
}
返回myobj;
}
}
}
如果您使用的是.Net 4,那么使用该类应该会非常有帮助。它将为您解决锁定问题。如果您使用的是.Net 4,那么使用该类将非常有帮助。它将为您解决锁定问题。只需使用ASP.Net缓存即可(您无需创建web应用程序,只需添加对System.web的引用即可):
简单易用,还意味着您的缓存现在还具有ASP.Net缓存的所有其他功能(缓存大小上限、缓存依赖项等)。只需使用ASP.Net缓存即可(您不需要创建web应用程序,只需添加对System.web
的引用即可):
简单易用,还意味着您的缓存现在还具有ASP.Net缓存的所有其他功能(缓存大小上限、缓存依赖项等)。为什么不尝试使用列表,插入一个包含您的值和插入值的时间戳的类项。然后,您可以搜索最新的时间戳和值,对结果列表排序,并使用最上面的项。然后,您可以根据需要终止旧项目。为什么不尝试使用列表,并插入一个具有您的值和插入值的时间戳的类项目。然后,您可以搜索最新的时间戳和值,对结果列表排序,并使用最上面的项。然后,您可以根据需要终止旧项。字典不是线程安全的,您应该在调用TryGetValue之前锁定,基本上,如果您使用的是字典,一次只能有一个东西接触它。字典不是线程安全的,您应该在调用TryGetValue之前锁定,基本上,如果您使用的是词典,一次只能有一种东西可以接触到它通常名称空间有很多很酷的数据结构,很少有人使用它们在第一段代码中,应该是internetServiceProviderCache[id]=myobj;应该是mydict[id]=myobj;应该是mydict[id]?通常名称空间有很多很酷的数据结构,使用它们的人不多。:(应该是mydict[name]=myobj;应该是mydict[id]=myobj;在第一个代码块中?internetServiceProviderCache[id]=myobj;应该是\u mydict[id]?倒数第二行代码应该是\u mydict.Add(id,myobj)
?这有关系吗?我得到的是“这个项目已经在收藏中了”这就是我这么做的原因。如果我们不能确切地看到你在做什么,很难判断什么是重要的。你完全确定没有更多的代码调用。添加字典或以其他方式操作它吗?第二行到最后一行的代码应该是\u myDict.Add(id,myobj)
?重要吗?我得到了答案“此项目已在集合中"这就是我这么做的原因。如果我们看不到你在做什么,很难判断什么是重要的。你完全确定没有更多的代码调用。添加字典或以其他方式操作它吗?我同意,系统中内置的ASP.NET缓存。Web命名空间工作得很好,让你不必编写所有这些东西您自己。缓存应用程序块也运行得很好。@user177883为什么?自2.0版以来,它一直是.Net framework的一部分,并且完全独立于ASP.Net framework,而不是对System.Web的引用。请查看此链接。在.Net 4.0上,您可以使用ObjectCache而不是ASP.Net缓存。framework文档建议仅在ASP.NET应用程序中使用HttpRuntime缓存。@rsbarro看起来非常有用-唉,海报和我都使用过时的技术(.NET 3.5)我同意,System.Web命名空间中内置的ASP.NET缓存工作得很好,使您不必自己编写所有这些内容。缓存应用程序块也工作得很好。@user177883为什么?它从2.0版起就是.NET framework的一部分,并且完全独立于ASP.NET framework,而不是Referencee到System.Web。请检查此链接。在.NET 4.0上,您可以使用ObjectCache而不是ASP.NET缓存。框架文档建议仅在ASP.NET应用程序中使用HttpRuntime缓存。@rsba
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);
}