473,378 Members | 1,679 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

Cache not invalidating immediately after file dependency changes

Hi

I'm running an ASP.NET web application under IIS. I'm inserting a cache
object with a file based CacheDependency. I've noticed that when the file
changes the Cache object is not always immediately invalidated.

e.g. Cache.Insert("myobj", data, new CacheDependency(filePath));

When I make a change to the file 'filePath' and call the object from the
cache it is not null. I'm disposing of the FileStream object immediately
after writing to the file.

e.g. data = Cache["myobj"];

However it appears to be null the second time it is called.

How can I guarantee the object is nulled immediately after the file
dependency has changed?

Thanks
Andrew
Oct 6 '08 #1
7 1988
Please find some code and further explanation of my problem:
public class SystemSettingsManager{ private const string _fileName =
"~/scs.config"; public static SystemSettings GetSettings() { HttpContext
context = HttpContext.Current; SystemSettings data =
(SystemSettings)context.Cache["SystemSettings"]; if (data != null)
Debug.WriteLine("Load SystemSettings from cache"); if (data ==
null) { Debug.WriteLine("Load SystemSettings from file");
XmlSerializer serializer = new XmlSerializer(typeof(SystemSettings)); try
{ string filePath = context.Server.MapPath(_fileName); FileStream
fs = new FileStream(filePath, FileMode.Open); data =
(SystemSettings)serializer.Deserialize(fs); fs.Close();
context.Cache.Insert("SystemSettings", data, new
acheDependency(filePath)); } catch (System.IO.FileNotFoundException)
{ data = new SystemSettings(); } } return data; } public
static void SaveSettings(SystemSettings settings) { HttpContext context
= HttpContext.Current; string filePath =
context.Server.MapPath(_fileName); XmlSerializer serializer = new
XmlSerializer(typeof(SystemSettings)); using (FileStream fs = new
FileStream(filePath, FileMode.Create)) { serializer.Serialize(fs,
settings); // added the flush and close to the using block but the problem
remains. fs.Flush(); // Clear all write buffers fs.Close(); // Explicitly
close stream } Debug.WriteLine("Save SystemSettings"); }}I can see
that when I update the FormView (with ObjectDataSource) I get the
following:Load SystemSettings from cacheSave SystemSettingsLoad
SystemSettings from cacheThis happens because the SystemSettings are already
cached somewhere else in the application.When I update the FormView again I
get:Load SystemSettings from fileSave SystemSettingsLoad SystemSettings from
cacheIf I keep doing it I get the same result. In other words it takes a
second call to the GetSettings method before the cache is empty. One other
thing is that when I debug with the Visual Studio web server it always works
as expected. It's only a problem with IIS. I've also tried on 2 different
IIS machines.I'm completely stuck.ThanksAndrew
Oct 9 '08 #2
Please find some code and further explanation of my problem:

public class SystemSettingsManager
{
private const string _fileName = "~/scs.config";

public static SystemSettings GetSettings()
{
HttpContext context = HttpContext.Current;
SystemSettings data =
(SystemSettings)context.Cache["SystemSettings"];
if (data != null) Debug.WriteLine("Load SystemSettings from cache");
if (data == null)
{
Debug.WriteLine("Load SystemSettings from file");

XmlSerializer serializer = new
XmlSerializer(typeof(SystemSettings));
try
{
string filePath = context.Server.MapPath(_fileName);
FileStream fs = new FileStream(filePath, FileMode.Open);
data = (SystemSettings)serializer.Deserialize(fs);
fs.Close();

context.Cache.Insert("SystemSettings", data, new
acheDependency(filePath));
}
catch (System.IO.FileNotFoundException)
{
data = new SystemSettings();
}
}
return data;
}

public static void SaveSettings(SystemSettings settings)
{
HttpContext context = HttpContext.Current;
string filePath = context.Server.MapPath(_fileName);
XmlSerializer serializer = new
XmlSerializer(typeof(SystemSettings));
using (FileStream fs = new FileStream(filePath, FileMode.Create))
{
serializer.Serialize(fs, settings);
// added the flush and close to the using block but the problem
remains.
fs.Flush(); // Clear all write buffers
fs.Close(); // Explicitly close stream
}
Debug.WriteLine("Save SystemSettings");
}

}

I can see that when I update the FormView (with ObjectDataSource) I get the
following:

Load SystemSettings from cache
Save SystemSettings
Load SystemSettings from cache

This happens because the SystemSettings are already cached somewhere else in
the application. When I update the FormView again I
get:

Load SystemSettings from file
Save SystemSettings
Load SystemSettings from cache

If I keep doing it I get the same result. In other words it takes a
second call to the GetSettings method before the cache is empty. One other
thing is that when I debug with the Visual Studio web server it always works
as expected. It's only a problem with IIS. I've also tried on 2 different
IIS machines.

I'm completely stuck.
Thanks
Andrew
Oct 9 '08 #3
Hi Andrew,

Sorry for the late reply. From your description you see "Load
SystemSettings from cache" even if the file is updated by executing
SaveSettings method, and it only happens when the web site is published,
correct?

I've tested the code you provided. It works fine. My IIS version is 5.1.

What I can guess is, some other code may cause this issue. I think I need
more code to investigate this issue (as you said, you updated the FormView.
What's the code?).

If it still doesn't work please tell me more details about your environment
(operating system, IIS version, Visual Studio version) and send me a demo
project. It will help me reproduce this issue. My email is
v-******@microsoft.com.

Regards,
Allen Chen
Microsoft Online Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
ms****@microsoft.com.

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subs...#notifications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://support.microsoft.com/select/...tance&ln=en-us.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.

--------------------
| From: "Andrew Jocelyn" <j0**@newsgroups.nospam>
| References: <eB**************@TK2MSFTNGP03.phx.gbl>
| Subject: Re: Cache not invalidating immediately after file dependency
changes
| Date: Thu, 9 Oct 2008 16:06:36 +0100
| Lines: 81
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.2900.5512
| X-RFC2646: Format=Flowed; Response
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5579
| Message-ID: <ux**************@TK2MSFTNGP06.phx.gbl>
| Newsgroups: microsoft.public.dotnet.framework.aspnet
| NNTP-Posting-Host: 88-97-199-158.dsl.zen.co.uk 88.97.199.158
| Path: TK2MSFTNGHUB02.phx.gbl!TK2MSFTNGP01.phx.gbl!TK2MSF TNGP06.phx.gbl
| Xref: TK2MSFTNGHUB02.phx.gbl
microsoft.public.dotnet.framework.aspnet:77602
| X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet
|
| Please find some code and further explanation of my problem:
|
| public class SystemSettingsManager
| {
| private const string _fileName = "~/scs.config";
|
| public static SystemSettings GetSettings()
| {
| HttpContext context = HttpContext.Current;
| SystemSettings data =
| (SystemSettings)context.Cache["SystemSettings"];
| if (data != null) Debug.WriteLine("Load SystemSettings from
cache");
| if (data == null)
| {
| Debug.WriteLine("Load SystemSettings from file");
|
| XmlSerializer serializer = new
| XmlSerializer(typeof(SystemSettings));
| try
| {
| string filePath = context.Server.MapPath(_fileName);
| FileStream fs = new FileStream(filePath, FileMode.Open);
| data = (SystemSettings)serializer.Deserialize(fs);
| fs.Close();
|
| context.Cache.Insert("SystemSettings", data, new
| acheDependency(filePath));
| }
| catch (System.IO.FileNotFoundException)
| {
| data = new SystemSettings();
| }
| }
| return data;
| }
|
| public static void SaveSettings(SystemSettings settings)
| {
| HttpContext context = HttpContext.Current;
| string filePath = context.Server.MapPath(_fileName);
| XmlSerializer serializer = new
| XmlSerializer(typeof(SystemSettings));
| using (FileStream fs = new FileStream(filePath, FileMode.Create))
| {
| serializer.Serialize(fs, settings);
| // added the flush and close to the using block but the
problem
| remains.
| fs.Flush(); // Clear all write buffers
| fs.Close(); // Explicitly close stream
| }
| Debug.WriteLine("Save SystemSettings");
| }
|
| }
|
| I can see that when I update the FormView (with ObjectDataSource) I get
the
| following:
|
| Load SystemSettings from cache
| Save SystemSettings
| Load SystemSettings from cache
|
| This happens because the SystemSettings are already cached somewhere else
in
| the application. When I update the FormView again I
| get:
|
| Load SystemSettings from file
| Save SystemSettings
| Load SystemSettings from cache
|
| If I keep doing it I get the same result. In other words it takes a
| second call to the GetSettings method before the cache is empty. One other
| thing is that when I debug with the Visual Studio web server it always
works
| as expected. It's only a problem with IIS. I've also tried on 2 different
| IIS machines.
|
| I'm completely stuck.
| Thanks
| Andrew
|
|
|

Oct 13 '08 #4
Hi Allen

I've replied to your email address with a test project.

Thanks
Andrew
Oct 14 '08 #5
Hi Andrew,

Thanks for your project. I've reproduced this issue on my side.

In my opinion, this issue is due to the fact that Cache module need to take
some time to check the dependency and this action is asynchronous to the
execution of the code in your SystemSettings class.Thus, the result is
unpredictable. As you said, some times it works and sometimes not.

After saving the file, if the check finished before the execution of this
line in the GetSettings method it will return null:
data = (SystemSettings)context.Cache["SystemSettings"];

Otherwise, it will return the cached data instead.

To solve this issue we can synchronize ourselves. By adding a flag we can
achieve this effect. Here's the code:

using System.Configuration;
using System.IO;
using System.Web;
using System.Web.Caching;
using System.Xml.Serialization;
using System.Diagnostics;
using System.Threading;
using System;
namespace Empetus.SCS.BLL
{
[System.ComponentModel.DataObject]
public class SystemSettingsManager
{
private const string _fileName = "~/scs.config";
private static bool _readfromfile = false;
private static object _mylock = new object();

[System.ComponentModel.DataObjectMethodAttribute(Sy stem.ComponentModel.DataO
bjectMethodType.Select, true)]
public static SystemSettings GetSettings()
{
HttpContext context = HttpContext.Current;
SystemSettings data;

lock (_mylock)
{
data = (SystemSettings)context.Cache["SystemSettings"];

if (data==null||_readfromfile)
{
context.Response.Write("Load SystemSettings from
file<br/>");

XmlSerializer serializer = new
XmlSerializer(typeof(SystemSettings));
try
{
string filePath = context.Server.MapPath(_fileName);
// create a filestream to read the XML document
FileStream fs = new FileStream(filePath,
FileMode.Open);
// use the Deserialize method to retrieve the oject
state
data = (SystemSettings)serializer.Deserialize(fs);
fs.Flush(); // Clear all write buffers
fs.Close();

context.Cache.Insert("SystemSettings", data, new
CacheDependency(filePath));

}
catch (System.IO.FileNotFoundException)
{
// if the file is not found, return a new empty
class
data = new SystemSettings();
}
}
else
{
context.Response.Write("Load SystemSettings from
cache<br/>");
}
_readfromfile = false;

}

return data;
}
[System.ComponentModel.DataObjectMethodAttribute(Sy stem.ComponentModel.DataO
bjectMethodType.Update, true)]
public static void SaveSettings(SystemSettings settings)
{
lock (_mylock)
{
HttpContext context = HttpContext.Current;
string filePath = context.Server.MapPath(_fileName);
XmlSerializer serializer = new
XmlSerializer(typeof(SystemSettings));

using (FileStream fs = new FileStream(filePath,
FileMode.Create))
{
serializer.Serialize(fs, settings);
fs.Flush(); // Clear all write buffers
fs.Close(); // Explicitly close stream
context.Cache.Insert("SystemSettings", settings, new
CacheDependency(filePath));
}
_readfromfile = true;
}
Debug.WriteLine("Save SystemSettings");
}
}
}
If a user saves the settings we can get notified via the _readfromfile
flag. It tells us to read from the file instead of the cache. Then in the
GetSettings method we can check the flag and read the data from the
appropriate place.
Please have a try and let me know if it works.

Regards,
Allen Chen
Microsoft Online Support

--------------------
| From: "Andrew Jocelyn" <j0**@newsgroups.nospam>
| References: <eB**************@TK2MSFTNGP03.phx.gbl>
<ux**************@TK2MSFTNGP06.phx.gbl>
<Bl**************@TK2MSFTNGHUB02.phx.gbl>
| Subject: Re: Cache not invalidating immediately after file dependency
changes
| Date: Tue, 14 Oct 2008 13:11:54 +0100
| Lines: 8
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.2900.5512
| X-RFC2646: Format=Flowed; Original
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5579
| Message-ID: <ea**************@TK2MSFTNGP05.phx.gbl>
| Newsgroups: microsoft.public.dotnet.framework.aspnet
| NNTP-Posting-Host: 88-97-199-158.dsl.zen.co.uk 88.97.199.158
| Path: TK2MSFTNGHUB02.phx.gbl!TK2MSFTNGP01.phx.gbl!TK2MSF TNGP05.phx.gbl
| Xref: TK2MSFTNGHUB02.phx.gbl
microsoft.public.dotnet.framework.aspnet:77846
| X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet
|
| Hi Allen
|
| I've replied to your email address with a test project.
|
| Thanks
| Andrew
|
|
|

Oct 15 '08 #6
Hi Allen

I think your analysis makes sense. I'm working on another project at the
moment so I won't be able to test your code for a couple of weeks. I'll
update you as soon as I have.

Thanks
Andrew
Oct 16 '08 #7
Hi Andrew,

Do you have any progress on this issue?

Regards,
Allen Chen
Microsoft Online Support
--------------------
| From: "Andrew Jocelyn" <j0**@newsgroups.nospam>
| References: <eB**************@TK2MSFTNGP03.phx.gbl>
<ux**************@TK2MSFTNGP06.phx.gbl>
<Bl**************@TK2MSFTNGHUB02.phx.gbl>
<ea**************@TK2MSFTNGP05.phx.gbl>
<Wr**************@TK2MSFTNGHUB02.phx.gbl>
| Subject: Re: Cache not invalidating immediately after file dependency
changes
| Date: Thu, 16 Oct 2008 10:18:30 +0100
| Lines: 10
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.2900.5512
| X-RFC2646: Format=Flowed; Original
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5579
| Message-ID: <#j**************@TK2MSFTNGP02.phx.gbl>
| Newsgroups: microsoft.public.dotnet.framework.aspnet
| NNTP-Posting-Host: 88-97-199-158.dsl.zen.co.uk 88.97.199.158
| Path: TK2MSFTNGHUB02.phx.gbl!TK2MSFTNGP01.phx.gbl!TK2MSF TNGP02.phx.gbl
| Xref: TK2MSFTNGHUB02.phx.gbl
microsoft.public.dotnet.framework.aspnet:77977
| X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet
|
| Hi Allen
|
| I think your analysis makes sense. I'm working on another project at the
| moment so I won't be able to test your code for a couple of weeks. I'll
| update you as soon as I have.
|
| Thanks
| Andrew
|
|
|

Oct 30 '08 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Dr Evil | last post by:
Greetings. Has anyone ever seen a tool that will read directories of header file source code and generate a dependency tree? I've often encountered large projects where such a tool would be useful....
11
by: Michael Gaab | last post by:
Compilation in c generally has four phases 1. Preprocessing 2. Compilation 3. Assembly 4. Linking. If I use a flag that will not link the code, order of compilation is not an issue,...
8
by: Christopher Harrison | last post by:
I would like to, cleanly, watch a flat file for changes (updates and the like). The file will be altered by another program... I found some example code (which actually didn't compile) on Google,...
4
by: hansiman | last post by:
in a class file (utils.vb) I'm trying to use cache, but get an error! I've tried to add imports cache namespace to utils.vb - but it does not work. What am I doing wrong?
14
by: MarcJ | last post by:
Hello, What I'm trying to do is monitor a log file for a certain line of text to be written to it. Once that text is written, I want to parse from that instance of the watched text until it...
3
by: TJO | last post by:
My asp.net 1.1 app is loading an xml file into cache so that subsequent calls for the xml file will not be pulled from the file system but from the cache instead. My method for loading the xml...
6
by: Rolf Welskes | last post by:
Hello, I want to partial cache by using a UserControl. Now I have a file dependency. In msdn I see it is not possible to do it the same way as in a page. The only information is to create a...
9
by: amanjsingh | last post by:
Does anyone know how to cache (or download and overwrite) a file from internet periodocally withouth using any server side script (PHP, ASP Coldfusion etc)? I want to display RSS feeds on my...
1
by: mcelrob5 | last post by:
I am writing an intranet application that uses Fusion Charts to display the results of a database query. My problem is the results are stored in an xml file that gets rewritten with each search. The...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.