asp.net cache and recycle worker processes

2019-07-31 19:19发布

So I've noticed that HttpContext.Cache is cleared whenever the worker process is recycled. I have a callback that reinserts the cached item back into the cache whenever it expires. However, this does not seem to happen when the process is recycled.

I have a call within my Application_Start that adds the appropriate items to the Cache but this does not seem to be called after the worker process is recycled. Is there a callback I can use to repopulate the cache on recycling or is it supposed to be Application_Start? Also, how can I test this locally?

I'm fairly certain I'm doing something wrong here.

3条回答
叼着烟拽天下
2楼-- · 2019-07-31 19:32

When the AppDomain is recycled, all assemblies are unloaded, and therefore all data is cleared. When the app restarts, it is essentially like starting from scratch, there is no way (as far as I am aware) of repopulating the cache this way.

This is different from stopping and starting the application, which basically saves the state of the application, and upon restart restores it's previous state (including the cache).

The only thing I can think of is to disable application recycling, but that's not recommended, as you'll end up with an ever-increasing cache size, which would become a bottleneck. You could possibly persist the data to a different caching mechanism, such as a SQL database.

查看更多
贼婆χ
3楼-- · 2019-07-31 19:38

Worked process recycle can be looked as stopping and starting the process holding .Net. All AppDomain data is lost.

From my understanding Application_Start is only executed when first request arrives. I'd expect the behaviour to be the same even after a recycle.

But if it doesn't execute (interesting) then you can always trigger it somewhere else. There are loads of ways to do that. For instance Application_BeginRequest or the ctor of any static class referencenced during first load.

Note that HttpContext.Cache is actually just a static object, so you can simply have a static bool isInitialized = false; that you change once init is done and it will be kept across requests. With a well-placed lock() {} it should run smoothly (so two requests don't start two initializations).

The way I usually solve it is to cache on demand. Not suitable for all solutions. Also I use Enterprise Framework or AppFabric to set a timeout (TTL) for the cache.

查看更多
4楼-- · 2019-07-31 19:39

The CacheItemPriority enumeration has a "NotRemovable" option that prevents the item from being removed from the cache during garbage collection.

From MSDN:

The cache items with this priority level will not be automatically deleted from the cache as the server frees system memory. However, items with this priority level are removed along with other items according to the item's absolute or sliding expiration time.

查看更多
登录 后发表回答