how to test cache existence
how to test cache existence
am 23.01.2008 02:36:07 von zino
in an asp.net 2.0 application, I create a dataset, cache it, and then when it
comes to retreive it, I test the cache first as :
" If HttpRuntime.Cache(itemKey) Is Nothing Then ... .. "
and if it's nothing then create the dataset and cache it ... .. .
the function works fine most of the time, but sporadically, once every while
it throws
"System.NullReferenceException: Object reference not set to an instance of
an object"
here is my code:
Public function GetAllClients(serviceCenter as string) as dataset
dim myDelegate as new CacheFactory.myDelegate(AddressOf
ClientDAL.GetAllClients)
dim myCache As Cache = CacheFactory.GetCachedItem("clientCode",
myDelegate)
dim ds As DataSet = ctype(myCache("clientCode"), DataSet) ' SOMETIME
THROWS System.NullReferenceException ERROR, because the cache was not
returned correctly from function 'GetCachedItem'
.... . ...
End Function
class CacheFactory
delegate function myDelegate() As dataSet
Public shared function GetCachedItem(itemKey as string, funct As
myDelegate) As Cache
If httpRuntime.Cache(itemKey) Is Nothing Then
dim ds As DataSet = funct.Invoke()
HttpRuntime.Cache.Insert(itemKey, ds, Nothing)
End If
Return HttpRuntime.Cache
End Function
end class
class ClientDAL
public shared function GetAllClients() As dataSet
' .... ... populate a dataset from database ...... .. ..
end function
end class
the application is under heavy load, and 99% of the time works fine, and
when it start throwing exception it last for ~2 minutes and then everything
goes back to normal.
I don't know if the issue is in the way I'm testing the cache existence or
because the "Shared" type of function "GetCachedItem" ?
RE: how to test cache existence
am 23.01.2008 09:45:12 von wawang
Hi zino,
It's possible your first call to HttpRuntime.Cache(itemKey) in the if
statement of GetCachedItem returns valid cache entry but the cache entry
might be removed when executing the second call to the Cache(itemKey) in
GetAllClients(); especially when the server is on high load.
I'm not sure why your GetCachedItem returns the entire Cache object instead
of an entry (object) saved in the Cache. If it were me, I probably will
write the GetCachedItem as:
Public shared function GetCachedItem(itemKey as string, funct as
MyDelegate) as object
dim obj as Object = HttpRuntime.Cache(itemKey)
if obj is Nothing then
obj = funct.Invoke()
HttpRuntime.Cache.Insert(itemKey, obj, Nothing)
End If
return obj
End Function
Now in GetAllClients(), you simply cast GetCachedItem("clientCode",
myDelegate) to a DataSet because you know either it succeeds or it raises
exception if the delegate fails to return a valid DataSet (inserting a
cache entry with null value will raise exception anyway).
Regards,
Walter Wang (wawang@online.microsoft.com, remove 'online.')
Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Re: how to test cache existence
am 24.01.2008 02:43:00 von Alvin Bruney
Good approach but I believe there is still an issue because it is a shared
function - static in C# - that is accessible by all threads. Since the cache
is also global and available to all threads/requests within the application,
the code needs to reflect this by protecting insertions and retrievals.
Essentially, I would either handle the null exception and do nothing - stick
your head in the sand approach. Or lock the resource and incur a performance
penalty but eliminate the null reference. That will/should protect you from
concurrent access and cache scavenging that can occur under heavy load while
you are accessing the cache. There's also another approach which should be
considered. Downgrade the cache to session so that global access is no
longer part of the design. Instead, on a per user basis, you can retrieve
the cached items. Of course, that's entirely dependent on what your
application is doing.
--
Regards,
Alvin Bruney [MVP ASP.NET]
[Shameless Author plug]
The O.W.C. Black Book, 2nd Edition
Exclusively on www.lulu.com/owc $19.99
-------------------------------------------------------
""Walter Wang [MSFT]"" wrote in message
news:u90KPxZXIHA.7336@TK2MSFTNGHUB02.phx.gbl...
> Hi zino,
>
> It's possible your first call to HttpRuntime.Cache(itemKey) in the if
> statement of GetCachedItem returns valid cache entry but the cache entry
> might be removed when executing the second call to the Cache(itemKey) in
> GetAllClients(); especially when the server is on high load.
>
> I'm not sure why your GetCachedItem returns the entire Cache object
> instead
> of an entry (object) saved in the Cache. If it were me, I probably will
> write the GetCachedItem as:
>
> Public shared function GetCachedItem(itemKey as string, funct as
> MyDelegate) as object
> dim obj as Object = HttpRuntime.Cache(itemKey)
> if obj is Nothing then
> obj = funct.Invoke()
> HttpRuntime.Cache.Insert(itemKey, obj, Nothing)
> End If
> return obj
> End Function
>
> Now in GetAllClients(), you simply cast GetCachedItem("clientCode",
> myDelegate) to a DataSet because you know either it succeeds or it raises
> exception if the delegate fails to return a valid DataSet (inserting a
> cache entry with null value will raise exception anyway).
>
> Regards,
> Walter Wang (wawang@online.microsoft.com, remove 'online.')
> Microsoft Online Community Support
>
> ==================================================
> When responding to posts, please "Reply to Group" via your newsreader so
> that others may learn and benefit from your issue.
> ==================================================
>
> This posting is provided "AS IS" with no warranties, and confers no
> rights.
>