I've got a problem with an app I've been working on, the Caching object and
events not firing correctly. In a nutshell: When I'm debugging, and I set a
breakpoint in the removed item call back, the code works correctly. If there
is no debugger it doesn't fire, which causes the app to have problems.
Here's what the code does: The TemplateData class inherits from the DataSet
Object, in the constructor it loads itself with Data from an XML file. I want
this to only happen at Application Start, OR if the file is changed, I want
it to reload the data. I add the TemplateData object to the cache and wire up
a dependency on the xml file that it's loading. If I don't have a break point
either in the Global.asax RefreshDataSetM ethod, OR in the constructor for the
TemplateData class, the data in the Cache does not get populated correctly.
That is to say when I go to get the TemplateData out of the cache, I get a
TemplateData object out, however none of the tables are populated.
As I was writing this I did some more testing and it appears that there are
certain times when the TemplateData is unable to load the file because some
other process has a hold on it. It appears that if you change the xml to a
new value, then change it back to the original values (with notepad) then
this crops up.
This is on Server 2003. Framework 1.1 VS2003.
Any ideas are GREATLY appreciated.
Here's the code for the Global.asax
using System.Collecti ons;
using System.Componen tModel;
using System.Web;
using System.Web.Sess ionState;
using System.Web.Cach ing;
using System.Data;
namespace Foo
{
/// <summary>
/// Summary description for Global.
/// </summary>
public class Global : System.Web.Http Application
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.Componen tModel.IContain er components = null;
private static Cache _appCache = null;
private static string _path = null;
// Event Handler for removing the data from the cache.
static void RefreshDataSet (String key, Object item,
CacheItemRemove dReason reason)
{
// Template Data is a class that inherits from the dataset object
TemplateData td = new
TemplateData(_p ath);
LoadCache(td);
}
static void LoadCache(Templ ateData td)
{
// Add the template to the cache, with no time expiration, just a file
dependency.
_appCache.Inser t("td", td, new CacheDependency (_path),
Cache.NoAbsolut eExpiration , Cache.NoSliding Expiration ,
CacheItemPriori ty.Normal, new CacheItemRemove dCallback(Refre shDataSet));
}
public Global()
{
InitializeCompo nent();
}
protected void Application_Sta rt(Object sender, EventArgs e)
{
// Figure out where we are in the world
_appCache =
System.Web.Http Context.Current .Cache;
_path = Server.MapPath( "ExpressTemplat es.xml");
// Load the TemplateData
TemplateData td = new TemplateData();
LoadCache(td);
}
protected void Session_Start(O bject sender, EventArgs e)
{
}
protected void Application_Beg inRequest(Objec t sender, EventArgs e)
{
}
protected void Application_End Request(Object sender, EventArgs e)
{
}
protected void Application_Aut henticateReques t(Object sender, EventArgs e)
{
}
protected void Application_Err or(Object sender, EventArgs e)
{
}
protected void Session_End(Obj ect sender, EventArgs e)
{
}
protected void Application_End (Object sender, EventArgs e)
{
}
#region Web Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeCompo nent()
{
this.components = new System.Componen tModel.Containe r();
}
#endregion
}
}
Here's the code for the TemplateData class
using System;
using System.Data;
using System.Xml;
using System.Collecti ons;
using System.Web;
namespace FOO
{
/// <summary>
/// Summary description for TemplateData.
/// </summary>
public class TemplateData :DataSet
{
public TemplateData()
{
this.ReadXml(Ht tpContext.Curre nt.Server.MapPa th("ExpressTemp lates.xml"));
}
public TemplateData(st ring path)
{
this.ReadXml(pa th);
}
}
}
Here's the code in a page load where it tries to retrieve the data from the
cache.
using System;
using System.Collecti ons;
using System.Componen tModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.Sess ionState;
using System.Web.UI;
using System.Web.UI.W ebControls;
using System.Web.UI.H tmlControls;
using System.Text;
using System.Web.Cach ing;
namespace FOO
{
/// <summary>
/// Summary description for ListExpressTemp lates.
/// </summary>
public class ListExpressTemp lates : System.Web.UI.P age
{
protected System.Web.UI.H tmlControls.Htm lForm Form1;
protected System.Web.UI.W ebControls.Plac eHolder PlaceHolder1;
protected TemplateTable tt;
protected System.Web.UI.W ebControls.Drop DownList DropDownList1;
protected StyleList sl;
private void Page_Load(objec t sender, System.EventArg s e)
{
//The system will use the offset and numberToDisplay Querystring values
to determine what to display.
// Get the Template data from the Cache
TemplateData td =
(TemplateData)C ache["td"];
sl = new StyleList(td);
int offset = Convert.ToInt32 (Request.QueryS tring["offset"]);
// numberToDisplay is determined by rows * cols
//int numberToDisplay =
Convert.ToInt32 (Request.QueryS tring["numberToDispla y"]);
int rows = Convert.ToInt32 (Request.QueryS tring["rows"]);
int cols = Convert.ToInt32 (Request.QueryS tring["cols"]);
if (rows ==0)
{
rows = 3;
}
if (cols == 0)
{
cols = 3;
}
int filterValue = Convert.ToInt32 (Request.QueryS tring["filter"]);
if (!Page.IsClient ScriptBlockRegi stered("Resubmi t"))
{
Page.RegisterCl ientScriptBlock ("Resubmit", reSubmitCode(ro ws, cols,
filterValue));
}
Filter filterToApply = (Filter)filterV alue;
TemplateList templateList = new TemplateList(fi lterToApply);
tt = new TemplateTable(r ows, cols, offset, templateList, true,
filterValue);
tt.CellPadding = 0;
tt.CellSpacing = 20;
tt.filterDropDo wn.SelectedInde x = filterValue;
tt.GridLines = GridLines.None;
PlaceHolder1.Co ntrols.Add(tt);
DropDownList1.D ataSource = sl.DataLoad();
DropDownList1.D ataValueField = "Name";
DropDownList1.D ataTextField = "FriendlyNa me";
DataBind();
}
private string reSubmitCode(in t rows, int cols, int filterValue)
{
StringBuilder sbScript = new StringBuilder() ;
sbScript.Append ("<script language=\"java script\">");
sbScript.Append ("function reSubmit(caller ){");
sbScript.Append ("var value = caller.value;") ;
sbScript.Append ("window.open(\ "ListExpressTem plates.aspx?row s=" + rows +
"&cols=" + cols + "&filter=\" + value" + ",\"_self\" )");
sbScript.Append ("} ");
sbScript.Append ("</script>");
return sbScript.ToStri ng();
}
#region Web Form Designer generated code
override protected void OnInit(EventArg s e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeCompo nent();
base.OnInit(e);
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeCompo nent()
{
this.Load += new System.EventHan dler(this.Page_ Load);
}
#endregion
}
}