asp.net cache multithreading locks webparts

跟風遠走 提交于 2019-12-06 07:51:06

You will want to take advantage of the lock keyword to make sure that the data is loaded and added to the cache in an atomic manner.

Update:

I modified the example to hold the lock accessing Cache for as short as possible. Instead of storing the data directly in the cache a proxy will be stored instead. The proxy will be created and added to the cache in an atomic manner. The proxy will then use its own locking to make sure that the data is only loaded once.

protected void Page_Load(object sender, EventArgs e)
{ 
   string key = "dtMine" + "_" + Session["UserID"].ToString();

   DataProxy proxy = null;

   lock (Cache)
   {
     proxy = Cache[key];
     if (proxy == null)
     {
       proxy = new DataProxy();
       Cache[key] = proxy;
     }
   }

   object data = proxy.GetData();
}

private class DataProxy
{
  private object data = null;

  public object GetData()
  {
    lock (this)
    {
      if (data == null)
      {
        data = LoadData(); // This is what actually loads the data.
      }
      return data;
    }
  }
}

Why don't you load the data and put it in the cache in the Application_Start in Global.asax, then no lock will be needed since locking Cache is a serious thing.

You could use a mutex around the test Cache["key"]==null:

The first thread acquires the lock, tests and sees that there's nothing in the cache and goes off to fetch the data. The second thread has to wait for the first to release the mutex. Once the second thread gets in the mutex, it tests, sees the data is there and then continues.

But this would lock up the thread that is running the Page_Load() method - probably a bad thing.

Perhaps a better solution would be to also test if the PageAsyncTask to fetch the data has been started? If not, start it. If so, you shouldn't start another so you may want to register your own event handler to catch when it completes...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!