Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / ASP.NET / Caching / November 2003

Tip: Looking for answers? Try searching our database.

How does the Cache object work internally?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jimmy [Used-Disks] - 04 Nov 2003 20:13 GMT
I have a set of global data which I want to cache, but I'm concerned about
how the Cache object stores its items. I do not want this global data to be
a performance bottle-neck, so I would like to know how it is actually being
stored.

Is it pooled? Is it per-thread (if so, are contents copied between threads
or re-built per thread)? Is it global to all threads (if so does the
framework handle thread saftey)?

Signature

-Jimmy

Alvin Bruney - 04 Nov 2003 23:22 GMT
Global data access by definition incurs a bottleneck if it is to be done
correctly since you must lock before access. A locked object blocks accessor
threads. cache contains references to objects. objects reside on the managed
heap it isnt part of a thread stack. What you need to be worried about is
the quantity of data being stored which will consume server resources.
Signature


-----------
Got TidBits?
Get it here: www.networkip.net/tidbits

> I have a set of global data which I want to cache, but I'm concerned about
> how the Cache object stores its items. I do not want this global data to be
[quoted text clipped - 4 lines]
> or re-built per thread)? Is it global to all threads (if so does the
> framework handle thread saftey)?
Jimmy [Used-Disks] - 06 Nov 2003 16:26 GMT
> Global data access by definition incurs a bottleneck if it is to be done
> correctly since you must lock before access.

Well, yes I know. That's why I asked *how* the data in the cache object is
stored. Do you know?

> A locked object blocks accessor
> threads. cache contains references to objects. objects reside on the managed
> heap it isnt part of a thread stack. What you need to be worried about is
> the quantity of data being stored which will consume server resources.

I am aware of these issues. I'm not sure why you brought them up as they do
not answer my question.

The question is: How does the cache store its items?

Potential answers include: Items are pooled and may have multiple instances.
The cache object is per-thread and relies on the IIS thread pooling
mechanism. The cache object is global to all threads. A combination of the
above.

Thanks -

Signature

-Jimmy

Alvin Bruney - 06 Nov 2003 19:29 GMT
Cache doesn't store objects, it stores references to objects. Whether or not
these references are pooled, I don't know the answer to that. My educated
guess: it shouldn't be pooled because it is not expensive to manipulate
references. Pooling is used to conserve resources

The references are stored on the main thread stack. The main thread objects
allow access by worker threads so yes in that sense it is global to all
threads.

Signature

-----------
Got TidBits?
Get it here: www.networkip.net/tidbits

> > Global data access by definition incurs a bottleneck if it is to be done
> > correctly since you must lock before access.
[quoted text clipped - 19 lines]
>
> Thanks -
Jimmy [Used-Disks] - 06 Nov 2003 21:44 GMT
> Cache doesn't store objects, it stores references to objects.

Who said otherwise?

I'm not interested in "what" the Cache stores, I'm only interested in "how."

> Whether or not
> these references are pooled, I don't know the answer to that.

Well, that's the only answer I'm looking for :-\

> My educated
> guess: it shouldn't be pooled because it is not expensive to manipulate
> references. Pooling is used to conserve resources

It can be expensive if a bunch of concurrent users are all trying to
manipulate the references at once. This is what would make a pool nice -
each representation of the pointer could be accessed by the user of the
current context without having to wait for other users.

> The references are stored on the main thread stack. The main thread objects
> allow access by worker threads so yes in that sense it is global to all
> threads.

Thanks for the educated guess, but I really need a solid answer. I've
searched MSDN and Google, but to no avail.

Signature

-Jimmy

Jerry III - 07 Nov 2003 08:39 GMT
> > Cache doesn't store objects, it stores references to objects.
>
[quoted text clipped - 15 lines]
> each representation of the pointer could be accessed by the user of the
> current context without having to wait for other users.

Cache is not pooled. There can be (and are) multiple cache objects but each
object has a single copy of the items stored in it. Cache locks are multiple
readers/single writer locks so you only incur performance hit if you store a
lot of objects that change constantly. But then - why would you ever store
an object like that in the first place? Cache is designed to store fairly
static objects that are going to be reused a lot. If you will update a
cached object on each request than it makes a lot more sense not to cache
that.

> > The references are stored on the main thread stack. The main thread
> objects
[quoted text clipped - 3 lines]
> Thanks for the educated guess, but I really need a solid answer. I've
> searched MSDN and Google, but to no avail.

Of course you can always reverse engineer the System.Web.Caching.Cache
class.

> --
> -Jimmy

Jerry
Jimmy [Used-Disks] - 07 Nov 2003 23:36 GMT
> > It can be expensive if a bunch of concurrent users are all trying to
> > manipulate the references at once. This is what would make a pool nice -
[quoted text clipped - 3 lines]
> Cache is not pooled. There can be (and are) multiple cache objects but each
> object has a single copy of the items stored in it.

So there can be multiple cache objects? Where did you come by this
information? If not in a pool, where are they stored?

Signature

-Jimmy

Jerry III - 08 Nov 2003 00:27 GMT
I should've read the docs more carefully - there's only one cache instance
per application domain. But still, I don't understand what exactly you'd
want to pool in a cache, are you talking about having multiple copies of all
the cached objects? And only be able to access each copy from one
client/thread, like database connections (where pooling makes sense as each
connection cannot be shared across multiple concurrent threads). I still do
not understand why would you even want to pool cache.

Jerry

> > > It can be expensive if a bunch of concurrent users are all trying to
> > > manipulate the references at once. This is what would make a pool nice -
[quoted text clipped - 10 lines]
> --
> -Jimmy
Jimmy [Used-Disks] - 08 Nov 2003 04:43 GMT
> I should've read the docs more carefully - there's only one cache instance
> per application domain.

Where did you read that? I have found nothing which states clearly one way
or another.

> But still, I don't understand what exactly you'd
> want to pool in a cache,

Nothing. I'm just trying to understand how the cache stores what it owns. A
pool is one of several options.

> are you talking about having multiple copies of all
> the cached objects?

One theory is that there may be multiple independent copies of the Cache
object. That could be one reason (aside from memory management, etcetera)
the existence of items stored in the cache is unreliable and that it is
necessary to check for null first and re-create data as needed.

> And only be able to access each copy from one
> client/thread, like database connections (where pooling makes sense as each
> connection cannot be shared across multiple concurrent threads). I still do
> not understand why would you even want to pool cache.

Here is a simple scenario. I have a DataSet which contains two tables:
Countries and Provinces. Each row in the Provinces table is linked to a
Country in the Countries table (your basic master/detail relationship). The
items in the provinces table are loaded on-demand so the states in the USA
are not loaded until an end-user needs to see the states available in the
USA.

Now here is the dilemma: How do I do these updates? If the Cache object is
instanced per-thread or is pooled, then I have no worries. I can simply get
the DataSet (reference_ from the Cache then fill/update it as necessary
without concerning myself about how other users will cause interaction with
the data because they will be executing in a separate context with a
separate instance of a Cache object. However, if the Cache is truly Global
(like the Application object) then I must ensure that the same set of
provinces isn't loaded twice in the same instance of the dataset.

The benefit of pooling is not having to worry about context: once an item is
drawn from the pool, no one else can see it (much less access it). The
drawback is extra memory consumption.

The worst thing, however, is not knowing which the Cache does! Each scenario
requires a different approach for manipulation and I cannot find any
documentation of which approach to use nor why.

Take a common example:

DataSet MyData = Cache["MyData"];
if(MyData == null){
 MyData = new MyDataSet();
 SomeAdapter.Fill(MyData);
 Cache["MyData"] = MyData;
}

Now imagine this code executing simultaneously in two separate threads of
the same application. What goes where? Do two datasets get created/filled,
but only one stored? Or do two get stored - one in each separate context?

> Jerry

Signature

-Jimmy

Jimmy [Used-Disks] - 10 Nov 2003 14:59 GMT
I've started a new thread with the example.

Signature

-Jimmy

Jerry III - 11 Nov 2003 07:07 GMT
Sorry it took me so long to reply:

> > I should've read the docs more carefully - there's only one cache instance
> > per application domain.
>
> Where did you read that? I have found nothing which states clearly one way
> or another.

http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemwebcachingcach
eclasstopic.asp - the Cache class documentation would seem like the very
obvious place to search for an information like this.

> Here is a simple scenario. I have a DataSet which contains two tables:
> Countries and Provinces. Each row in the Provinces table is linked to a
> Country in the Countries table (your basic master/detail relationship). The
> items in the provinces table are loaded on-demand so the states in the USA
> are not loaded until an end-user needs to see the states available in the
> USA.

You just cache the list of counties for each state. Like this:

string    State;    // Put your state selection here
string[]  CountyList = (string[])Cache["state-" + State];
if( CountyList == null )
{
   // Load the list of counties here
   Cache["state-" + State] = CountyList;    // You should rpobably use
Insert
}

> Now here is the dilemma: How do I do these updates? If the Cache object is
> instanced per-thread or is pooled, then I have no worries. I can simply get
[quoted text clipped - 25 lines]
> the same application. What goes where? Do two datasets get created/filled,
> but only one stored? Or do two get stored - one in each separate context?

It will not work, there is one cache shared accross all requests (well,
across one application domain). You need to cache data that will be the same
for each request, like list of counties in each state, not session state
information. If you really want to go that way store it in a session - but
in this case it makes absolutely no sense as the list of counties wil be the
same in a given state for alll requests (and if it wasn't, let's say due to
user restrictions then it has no place in the cache).

Remember, caching only makes sense if it's reused over a lot of requests.
Don't put your state objects there.

> > Jerry
>
> --
> -Jimmy
Jimmy [Used-Disks] - 11 Nov 2003 14:15 GMT
http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemwebcachingcach
> eclasstopic.asp - the Cache class documentation would seem like the very
> obvious place to search for an information like this.

Hey Jerry, thanks for the answer. Somehow I must have missed this page
(don't know how though! <g>).

Signature

-Jimmy

Bored Stiff - 11 Nov 2003 10:14 GMT
> DataSet MyData = Cache["MyData"];
> if(MyData == null){
>   MyData = new MyDataSet();
>   SomeAdapter.Fill(MyData);
>   Cache["MyData"] = MyData;
> }

> Now imagine this code executing simultaneously in two
> separate threads of
> the same application. What goes where? Do two datasets
> get created/filled,
> but only one stored? Or do two get stored - one in each
> separate context?

Look at the MSDN documentation for the Cache class: "... One instance of
this class is created per application domain ...".

In the above scenario two get created/filled and one reference is
stored, overwriting any previous reference.

Note that in addition to HttpContext.Cache and Page.Cache, you can
reference the cache for your application domain using the static
property HttpRuntime.Cache.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.