锁定和简单缓存

发布于 2024-10-19 19:07:47 字数 1524 浏览 2 评论 0原文

我有以下代码。当部署到服务器时,我收到异常,该对象已存在于字典中。即使我做了双重锁定,同步效果也不太好。实现这一点的最佳方法是什么?我怎样才能最好地锁定对此部分的访问?我应该实现一个单例类并将方法放在其中吗?

我应该锁定集合还是互斥锁?

不,我不在.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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

爱已欠费 2024-10-26 19:07:47

字典的读取不是线程安全的,您应该在调用 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

满天都是小星星 2024-10-26 19:07:47

如果您使用 .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.

谁许谁一生繁华 2024-10-26 19:07:47

只需使用 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 缓存的所有其他功能(缓存大小上限、缓存依赖项等...)

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):

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);
}

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...)

笑,眼淚并存 2024-10-26 19:07:47

为什么不尝试使用列表,并插入一个项目,该项目是一个包含您的值和插入该值的时间戳的类。然后,您可以搜索最新的时间戳和值,对结果列表进行排序,并使用顶部项目。然后,您可以根据需要使旧项目过期。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文