1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
// <copyright file="ObjectCacheHost.cs" company="Microsoft">
// Copyright (c) 2009 Microsoft Corporation. All rights reserved.
// </copyright>
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Caching;
using System.Runtime.Caching.Hosting;
using System.Web.Util;
namespace System.Web.Hosting {
[SuppressMessage("Microsoft.Usage", "CA2302:FlagServiceProviders", Justification = "Internal class")]
internal sealed class ObjectCacheHost : IServiceProvider, IApplicationIdentifier, IFileChangeNotificationSystem, IMemoryCacheManager
{
private Object _lock = new Object();
private Dictionary<MemoryCache, MemoryCacheInfo> _cacheInfos;
internal sealed class FileChangeEventTarget {
private OnChangedCallback _onChangedCallback;
private FileChangeEventHandler _handler;
private void OnChanged(Object sender, FileChangeEvent e) {
_onChangedCallback(null);
}
internal FileChangeEventHandler Handler { get { return _handler; } }
internal FileChangeEventTarget(OnChangedCallback onChangedCallback) {
_onChangedCallback = onChangedCallback;
_handler = new FileChangeEventHandler(this.OnChanged);
}
}
internal sealed class MemoryCacheInfo {
internal MemoryCache Cache;
internal long Size;
}
Object IServiceProvider.GetService(Type service) {
if (service == typeof(IFileChangeNotificationSystem)) {
return this as IFileChangeNotificationSystem;
}
else if (service == typeof(IMemoryCacheManager)) {
return this as IMemoryCacheManager;
}
else if (service == typeof(IApplicationIdentifier)) {
return this as IApplicationIdentifier;
}
else {
return null;
}
}
String IApplicationIdentifier.GetApplicationId() {
return HttpRuntime.AppDomainAppId;
}
void IFileChangeNotificationSystem.StartMonitoring(string filePath, OnChangedCallback onChangedCallback, out Object state, out DateTimeOffset lastWrite, out long fileSize) {
if (filePath == null) {
throw new ArgumentNullException("filePath");
}
if (onChangedCallback == null) {
throw new ArgumentNullException("onChangedCallback");
}
FileChangeEventTarget target = new FileChangeEventTarget(onChangedCallback);
FileAttributesData fad;
HttpRuntime.FileChangesMonitor.StartMonitoringPath(filePath, target.Handler, out fad);
if (fad == null) {
fad = FileAttributesData.NonExistantAttributesData;
}
state = target;
#if DBG
Debug.Assert(fad.UtcLastWriteTime.Kind == DateTimeKind.Utc, "fad.UtcLastWriteTime.Kind == DateTimeKind.Utc");
#endif
lastWrite = fad.UtcLastWriteTime;
fileSize = fad.FileSize;
}
void IFileChangeNotificationSystem.StopMonitoring(string filePath, Object state) {
if (filePath == null) {
throw new ArgumentNullException("filePath");
}
if (state == null) {
throw new ArgumentNullException("state");
}
HttpRuntime.FileChangesMonitor.StopMonitoringPath(filePath, state);
}
void IMemoryCacheManager.ReleaseCache(MemoryCache memoryCache) {
if (memoryCache == null) {
throw new ArgumentNullException("memoryCache");
}
lock (_lock) {
if (_cacheInfos != null) {
MemoryCacheInfo info = null;
if (_cacheInfos.TryGetValue(memoryCache, out info)) {
_cacheInfos.Remove(memoryCache);
}
}
}
}
void IMemoryCacheManager.UpdateCacheSize(long size, MemoryCache memoryCache) {
if (memoryCache == null) {
throw new ArgumentNullException("memoryCache");
}
lock (_lock) {
if (_cacheInfos == null) {
_cacheInfos = new Dictionary<MemoryCache, MemoryCacheInfo>();
}
MemoryCacheInfo info = null;
if (!_cacheInfos.TryGetValue(memoryCache, out info)) {
info = new MemoryCacheInfo();
info.Cache = memoryCache;
_cacheInfos[memoryCache] = info;
}
info.Size = size;
}
}
internal long TrimCache(int percent) {
long trimmedOrExpired = 0;
MemoryCache[] caches = null;
lock (_lock) {
if (_cacheInfos != null && _cacheInfos.Count > 0) {
caches = new MemoryCache[_cacheInfos.Keys.Count];
_cacheInfos.Keys.CopyTo(caches, 0);
}
}
if (caches != null) {
foreach (MemoryCache cache in caches) {
trimmedOrExpired += cache.Trim(percent);
}
}
return trimmedOrExpired;
}
}
}
|