I will start by looking at the following question:
... is that sometimes Cache returns null ...
This may be due to the fact that, apparently, it takes some time to fill the cache with a background thread. When Application_Start fires, you start the background thread and then terminate Application_Start . Then the application can move on to other tasks, for example, process the page.
If during page processing an attempt is made to access the cache until the initial start of AddDataInCache , the cache will return null.
As for memory consumption, I donβt immediately see how you could improve the situation if you could not reduce the number of rows in cached data tables.
The first time AddDataInCache called AddDataInCache cache is empty to begin with. Then your GetAllDataForCaching creates two data tables and populates them with data. This forces the process to save memory for storing data in DataTables.
In the second and subsequent calls to AddDataInCache cache already contains all the data that was received at the previous start. And again, you create two new data and fill it with data. This results in a memory return to hold both existing data in the cache and new data in the DataTables created in the second run. Then, as soon as the second run finishes loading the data, you overflow the existing data in the cache with the new data obtained in the second run.
At this point, the data in the cache from the first start will have the right to garbage collection . But this does not mean that the memory will be immediately restored. Memory will be restored when the garbage collector arrives and notices that DataTables are no longer needed in memory.
Please note that cached items from the first launch will only have the right to garbage collection if no live objects contain a link to them. Make sure you keep using the cache for a short time.
And while all this is happening, your background thread will happily continue the business, refreshing the cache. Therefore, it is possible that the third cache update occurs before the garbage collector frees up memory for DataTables retrieved in the first run, resulting in even greater memory consumption.
Therefore, in order to reduce memory consumption, I think you just have to reduce the amount of data stored in the cache (fewer rows, fewer columns). It may also be useful to increase the time between cache updates.
Finally, make sure that you do not keep old versions of cached objects alive by referencing them in long-running application requests / processes.