140 lines
5.3 KiB
C#
140 lines
5.3 KiB
C#
|
// <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;
|
||
|
}
|
||
|
}
|
||
|
}
|