Asp.net cache multithreading blocks web pages

I have the following script:

Suppose we have two different web pages that run on the same data - one pie chart, the other a data table. in their Page_Load, they asynchronously load data from the database and load it into the application cache for further use or use by other web parts. Thus, each web part has code similar to this:

protected void Page_Load(object sender, EventArgs e) { if (Cache["dtMine" + "_" + Session["UserID"].ToString()]==null) { ... Page.RegisterAsyncTask(new PageAsyncTask( new BeginEventHandler(BeginGetByUserID), new EndEventHandler(EndGetByUserID), null, args, true)); } else { get data from cache and bind to controls of the webpart } } 

Since both web pages work with the same data, it makes no sense for me to execute the code twice.

What is the best approach for one web part to exchange information with another "I am already receiving data, so just wait until I put it in the cache"?

I consider a mutex, a lock, assign a temporary value to a cache element and wait until that temporary value changes ... many parameters - what should I use.

+2
source share
3 answers

You want to use the lock keyword to make sure the data is loaded and added to the cache in an atomic way.

Update:

I modified the example to lock access to the Cache lock as short as possible. Instead of storing data directly in the cache, a proxy server will be saved instead. A proxy server will be created and added to the cache in an atomic way. The proxy will then use its own lock to make sure that the data is downloaded only 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; } } } 
+2
source

Why don’t you load the data and cache it in Application_Start in Global.asax, then you won’t need any blocking, as Cache blocking is a serious thing.

+1
source

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

The first thread receives a lock, checks and sees that there is nothing in the cache, and is sent to fetch data. The second thread must wait for the first to release the mutex. As soon as the second thread enters the mutex, it checks to see if the data is visible, and then continues.

But that would block the thread that starts the Page_Load() method - maybe this is bad.

Perhaps the best solution would also be to check if PageAsyncTask is PageAsyncTask to retrieve the data? If not, run it. If so, you should not run another, so you might want to register your own event handler to catch when it will end ...

0
source

All Articles