How should I write cached data?

Last post 10-15-2009 2:21 AM by Robert Barnes. 2 replies.

Sort Posts:

  • How should I write cached data?

    10-14-2009, 11:27 PM
    • Member
      235 point Member
    • Robert Barnes
    • Member since 09-01-2006, 1:05 AM
    • Auckland, New Zealand
    • Posts 460

    Summary

    I am using Cache to serve advertisments, and to accumulate display and click counts.  This all works very efficiently, but the usage data is accummulated in memory.   I want this in-memory data to be written to the database at least once a day, plus if the application terminates.  What is the best way of doing this?  I have thought of using a timer, or perhaps there areCache events I can use.  Or something else.

    Detail

    By cacheing the Advertisements datatable and the count array in which statistics are accumulated, the time to serve an ad was reduced from 16milliseconds to 0 milliseconds.  I am using an ImageButton rather than an Adrotator as I found it easier to duplicate the Adrotator function explicitly than to figure out how to get information on which ad was being displayed.

    A group of related Cache objects are created in the Pre-Render event of my master page, like this: -

           If IsNothing(Cache("tbadvert")) Then
                Dim taAdvert As New AdvertiserTableAdapters.AdvertismentsTableAdapter
                Dim tbAdvert As Advertiser.AdvertismentsDataTable
                tbAdvert = taAdvert.GetData
                Cache("tbadvert") = tbAdvert
                Dim Upbound As Integer = tbAdvert.Count - 1
                Dim AdvertCountTable(Upbound, 2) As Integer
                Cache("AdvertCountTable") = AdvertCountTable
                Dim trAdvert As Advertiser.AdvertismentsRow
                Dim AdvertIDTable(Upbound) As Guid
                For Subscr As Integer = 0 To Upbound
                    trAdvert = tbAdvert(Subscr)
                    AdvertIDTable(Subscr) = trAdvert.AVTid
                Next
                Cache("AdvertIDTable") = AdvertIDTable
            End If

    Immediately following (still in pre-render) the page chooses (randomly) an ad to display, and adds 1 to the relevant impression count: -

            If Cache("tbadvert").count = 0 Then
                ImbHeaderAd1.Visible = False
            Else
                Dim R As New Random
                Dim Subscr As Integer = R.Next Mod Cache("tbadvert").Count
                Dim trAdvert As Advertiser.AdvertismentsRow = Cache("tbadvert")(Subscr)
                ImbHeaderAd1.ImageUrl = "~/HttpHandlers/avtimage.ashx?id=" & Subscr
                ImbHeaderAd1.PostBackUrl = "~/Admin_Pages/adredirect.aspx?ID=" & Subscr
                Cache("AdvertCountTable")(Subscr, 0) += 1
            End If

    The redirect page Admin_Pages/adredirect.aspx executes this code in its Page_Load, adding one to the click count and then redirecting to the appropriate page: -

            Dim Subscr As Integer = Request("ID")
            Dim trAdvert As Advertiser.AdvertismentsRow = Cache("tbadvert")(Subscr)
            Cache("AdvertCountTable")(Subscr, 1) += 1
            Response.Redirect("http://" & trAdvert.AVTNavigateURL)

    So far so good, although I'm concerned about an issue: -

    Question 1.  

    I have used "IsNothing(Cache("tbadvert"))" as a single test for all of the related cache objects.  Is this safe code?  Or would it be better practice to put all of these objects into a single structure, creating a type like this and cacheing it as a single unit? 

         Structure AdData
               Dim tbAdvert As Advertiser.AdvertismentsDataTable
               Dim Ubound as Integer
               Dim AdCounts(Ubound, 1) as Integer
         End Structure

    I read that there were some overheads with structures and so I used independent variables, but I'm concerned that I may have introduced some subtle error possibilities through possiblities of the cache entries being independently created and/or released.

    Continuing...

    Anyway, so far so good, this all works perfectly, and is very fast, but of course the statistics are accumulated in memory.  For testing I wrote a subroutine that writes the data out when I click a button: -
         Sub WriteAdCounts()
            '   Write out accumulated Ad statistics, then clear table for next time
            If IsNothing(Context.Cache("AdvertCountTable")) Then    '   Defensive
                Exit Sub
            End If

            Dim Ubound As Integer = Context.Cache("tbadvert").Count - 1
            Dim taAdCount As New AdvertiserTableAdapters.AdCountsTableAdapter
            Dim RecordTime As DateTime = Now()   '   All records of batch have the same timestamp, rather than using Now() directly
            For Subscr As Integer = 0 To Ubound
                taAdCount.Insert(Subscr, RecordTime, Context.Cache("AdvertIDTable")(Subscr), Context.Cache("AdvertCountTable")(Subscr, 0), _
                                 Context.Cache("AdvertCountTable")(Subscr, 1))
                Context.Cache("AdvertCountTable")(Subscr, 0) = 0
                Context.Cache("AdvertCountTable")(Subscr, 1) = 0
            Next
        End Sub

    Question 2

    How do I get this to execute automatically, at least once a day, and if the cache is destroyed. I wondered about using a timer in Global.asax, but I couldn't seem to hook up any event code to this, and also it would have left unhandled the issue of "what if the cache is cleared?".   Perhaps there are cache events that I can hook up to.

    Thank you, Robert Barnes

  • Re: How should I write cached data?

    10-15-2009, 1:25 AM
    • Member
      461 point Member
    • harsh.cer
    • Member since 07-24-2009, 10:36 AM
    • Posts 68
  • Re: How should I write cached data?

    10-15-2009, 2:21 AM
    • Member
      235 point Member
    • Robert Barnes
    • Member since 09-01-2006, 1:05 AM
    • Auckland, New Zealand
    • Posts 460

    Thank you, but I've read through those articles and they are similar to others that I've read, and tell me how to do the bits that I've already done.  But I'm still no closer to answering my two questions: -

    1.  Should I create a structure to cache rather than caching three independent objects?

    2.  How do I write the cached statistics table?

    Regards, Robert


Page 1 of 1 (3 items)