CacheDependency.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. //
  2. // System.Web.Caching.CacheDependency
  3. //
  4. // Authors:
  5. // Patrik Torstensson
  6. // Gonzalo Paniagua Javier ([email protected])
  7. //
  8. // (c) 2003 Ximian, Inc. (http://www.ximian.com)
  9. //
  10. using System;
  11. using System.IO;
  12. using System.Web;
  13. namespace System.Web.Caching
  14. {
  15. internal class CacheDependencyChangedArgs : EventArgs
  16. {
  17. string key;
  18. public CacheDependencyChangedArgs (string key)
  19. {
  20. this.key = key;
  21. }
  22. public string Key {
  23. get { return key; }
  24. }
  25. }
  26. internal delegate void CacheDependencyChangedHandler (object sender, CacheDependencyChangedArgs args);
  27. public sealed class CacheDependency : IDisposable
  28. {
  29. static string [] noStrings = new string [0];
  30. static CacheDependency noDependency = new CacheDependency ();
  31. DateTime start;
  32. bool changed;
  33. bool disposed;
  34. CacheEntry [] entries;
  35. CacheItemRemovedCallback removedDelegate;
  36. FileSystemWatcher [] watchers;
  37. private CacheDependency ()
  38. {
  39. }
  40. public CacheDependency (string filename)
  41. : this (filename, DateTime.MaxValue)
  42. {
  43. }
  44. public CacheDependency (string filename, DateTime start)
  45. : this (new string [] {filename}, null, null, start)
  46. {
  47. }
  48. public CacheDependency (string [] filenames)
  49. : this (filenames, null, null, DateTime.MaxValue)
  50. {
  51. }
  52. public CacheDependency (string [] filenames, DateTime start)
  53. : this (filenames, null, null, start)
  54. {
  55. }
  56. public CacheDependency (string [] filenames, string [] cachekeys)
  57. : this (filenames, cachekeys, null, DateTime.MaxValue)
  58. {
  59. }
  60. public CacheDependency (string [] filenames, string [] cachekeys, DateTime start)
  61. : this (filenames, cachekeys, null, start)
  62. {
  63. }
  64. public CacheDependency (string [] filenames, string [] cachekeys, CacheDependency dependency)
  65. : this (filenames, cachekeys, dependency, DateTime.MaxValue)
  66. {
  67. }
  68. public CacheDependency (string [] filenames,
  69. string [] cachekeys,
  70. CacheDependency dependency,
  71. DateTime start)
  72. {
  73. Cache cache = HttpRuntime.Cache;
  74. this.start = start;
  75. if (filenames == null)
  76. filenames = noStrings;
  77. foreach (string file in filenames) {
  78. if (file == null)
  79. throw new ArgumentNullException ("filenames");
  80. }
  81. if (cachekeys == null)
  82. cachekeys = noStrings;
  83. int missing_keys = 0;
  84. foreach (string ck in cachekeys) {
  85. if (ck == null)
  86. throw new ArgumentNullException ("cachekeys");
  87. if (cache.GetEntry (ck) == null)
  88. missing_keys++;
  89. }
  90. if (dependency == null)
  91. dependency = noDependency;
  92. this.changed = dependency.changed;
  93. if (changed == true)
  94. return;
  95. int nentries = cachekeys.Length + ((dependency.entries == null) ? 0 :
  96. dependency.entries.Length) - missing_keys;
  97. if (nentries != 0) {
  98. this.removedDelegate = new CacheItemRemovedCallback (CacheItemRemoved);
  99. this.entries = new CacheEntry [nentries];
  100. int i = 0;
  101. if (dependency.entries != null) {
  102. foreach (CacheEntry entry in dependency.entries) {
  103. entry._onRemoved += removedDelegate;
  104. entries [i++] = entry;
  105. }
  106. }
  107. for (int c=0; c<cachekeys.Length; c++) {
  108. CacheEntry entry = cache.GetEntry (cachekeys [c]);
  109. if (entry == null)
  110. continue;
  111. entry._onRemoved += removedDelegate;
  112. entries [i++] = entry;
  113. }
  114. }
  115. if (filenames.Length > 0) {
  116. watchers = new FileSystemWatcher [filenames.Length];
  117. for (int i=0; i<filenames.Length; i++)
  118. watchers [i] = CreateWatcher (filenames [i]);
  119. }
  120. }
  121. private FileSystemWatcher CreateWatcher (string file)
  122. {
  123. FileSystemWatcher watcher = new FileSystemWatcher ();
  124. watcher.Path = Path.GetFullPath (Path.GetDirectoryName (file));
  125. watcher.Filter = Path.GetFileName (file);
  126. watcher.Changed += new FileSystemEventHandler (OnFileChanged);
  127. watcher.Created += new FileSystemEventHandler (OnFileChanged);
  128. watcher.Deleted += new FileSystemEventHandler (OnFileChanged);
  129. watcher.EnableRaisingEvents = true;
  130. return watcher;
  131. }
  132. private void OnFileChanged (object sender, FileSystemEventArgs e)
  133. {
  134. OnChanged (sender, e);
  135. }
  136. void CacheItemRemoved (string key, object value, CacheItemRemovedReason reason)
  137. {
  138. OnChanged (this, EventArgs.Empty);
  139. }
  140. void OnChanged (object sender, EventArgs args)
  141. {
  142. if (changed || disposed)
  143. return;
  144. changed = true;
  145. if (Changed != null)
  146. Changed (this, new CacheDependencyChangedArgs (null));
  147. }
  148. public void Dispose ()
  149. {
  150. for (int i=0; i<watchers.Length; i++)
  151. watchers [i].Dispose ();
  152. }
  153. public bool HasChanged
  154. {
  155. get { return changed; }
  156. }
  157. internal CacheEntry [] GetCacheEntries ()
  158. {
  159. return entries;
  160. }
  161. internal event CacheDependencyChangedHandler Changed;
  162. }
  163. }