Reputation: 968
I'm using the attribute [OutputCache(Duration=XXX)]
(and also the donut variant [DonutOutputCache(Duration=XXX)]
).
However I noticed (confirmed by ASP.NET (MVC) Outputcache and concurrent requests) this is not thread safe: when the cache is re-generated, if the controller method is slow enough (and it's usually the case, this is why you cache it ^^), multiple "identical" requests can enter the action an perform the operations, instead of having only 1 request processed, blocking the other requests and serving them from the cache.
Is there any way to easily make a blocking/thread safe OutputCache
attribute? Same question for DonutOutputCache
? Like [BlockingOutputCache(SameParameters)]
and [BlockingDonutOutputCache(SameParameters)]
Note: cached actions are regular actions, returning View(model)
, heavy work is done in the action and in the view (the view can do something very simple like @Model.GetPrice() which translates to heavy lifting in the backend).
Thanks!
Edit: another way could be to create a [BlockingAction(BlockingParameters)]
attribute that would block subsequent requests to this action when not served from the cache.
Upvotes: 3
Views: 686
Reputation: 2973
You could use the VaryByCustom. In Global.asax override the GetVaryByCustomString method. Then create unique cache key, and use double checked locking on your cache storage. It's sync way. I may guess that exists async way when you begin cache resolving and then end cache resolving.
Upvotes: 1