I've written a DLL that may be used in a number of ways (referenced by ASP.NET web sites, WinForms, etc.). It needs to load its data from several delimited files that will be automatically updated on a semi-regular basis. For performance reasons, I'm loading the data into a static object (a generic List), and only want to go back to the files when the data changes. (The amount of data doesn't take up an unreasonable amount of memory, but it does take too long to read from the file on every access). I've tried using a FileSystemWatcher, but that's proven unreliable - it periodically misses file updates. Since I can't count on the DLL running inside a web site, the ASP.NET CacheDependency option doesn't seem appropriate. Has anyone found a good solution to this sort of thing?
Have you looked at the Enterprise Library Caching application block? It allows for cache invalidation on a number of different events,including file changes (AFAIK), and does not require ASP.NET (and yet, integrates well with it). You can find it here:
You could save the last date you loaded from the the file as another file in the same directory, or in a static date time in your class. I think the last solution is probably not what you are looking for since you can't count on your class being loaded. I would also consider saving and comparing an MD5 hash of the file to see when it changes.
My solution to this problem has been to re-load the data file periodically: once per hour, for example. It depends on how critical it is that your program have exact up to the minute data.
Perhaps a hybrid approach is called for. Use FileSystemWatcher, but also save the last file date/time (as suggested above), and periodically check the current date/time on the file. If they differ, then reload the file. That would be my preferred solution if it were important to keep the data up to date.
You could also build in a way to notify your program when it needs to reload the data.
The ASP.NET Cache and associated CacheDependency has no dependency on ASP.NET, IIS, or a web server. You are free to use it for this exact situation. It requires much less effort to get working than the Enterprise Library Caching Application Block and is more widely used and documented.
Some additional reference: http://aspalliance.com/1705_A_New_Approach_to_HttpRuntimeCache_Management.all
If you want to use the ASP.NET Cache logic in your DLL, simply wrap it and reference it like so:
using System.Web.Caching;
...
var cache = HttpRuntime.Cache;
cache.Insert("foo", foo);
This code, along with any FileSystemDependency you care to add to it, will work equally well in your library regardless of whether or not it is running in a web, winform, console, or service context.
You can also do this if you want to be sure to use the same cache as the web, but it's optional:
HttpContext context = HttpContext.Current;
if(context != null)
{
_cache = context.Cache;
}
else
{
_cache = HttpRuntime.Cache;
}