static CICache() { PostEvictionDelegate del = new PostEvictionDelegate(OnRemovalCallBack); policy = new MemoryCacheEntryOptions(); policy.RegisterPostEvictionCallback(del); }
/// <summary> /// 向内存缓存对象中插入一条记录,并基于时间依赖 /// </summary> /// <typeparam name="TItem"></typeparam> /// <param name="cache"></param> /// <param name="key"></param> /// <param name="value"></param> /// <param name="dependency"></param> /// <param name="callbackHandler"></param> public static void Set <T>(this IMemoryCache cache, string key, T value, TimeCacheDependency dependency, PostEvictionDelegate callbackHandler = null ) { var options = new MemoryCacheEntryOptions(); if (null != callbackHandler) { //注册回调事件 options.RegisterPostEvictionCallback(callbackHandler); } if (dependency.Policy == CacheItemPolicy.AbsoluteExpiration) { options.SetAbsoluteExpiration(dependency.Time); } else { options.SetSlidingExpiration(dependency.Time); } cache.Set(key, value, options); }
private static void InvokeCallbacks(CacheEntry entry) { var callbackRegistrationList = Interlocked.Exchange(ref entry._postEvictionCallbacks, null); if (callbackRegistrationList == null) { return; } foreach (var callbackRegistration in callbackRegistrationList) { try { PostEvictionDelegate evictionCallback = callbackRegistration.EvictionCallback; if (evictionCallback != null) { object key = entry.Key; object obj = entry.Value; EvictionReason evictionReason = entry.EvictionReason; object state = callbackRegistration.State; evictionCallback.Invoke(key, obj, evictionReason, state); } } catch (Exception ex) { } } }
/// <summary> /// The given callback will be fired after the cache entry is evicted from the cache. /// </summary> /// <param name="entry">The <see cref="ICacheEntry"/>.</param> /// <param name="callback">The callback to run after the entry is evicted.</param> /// <returns>The <see cref="ICacheEntry"/> for chaining.</returns> public static ICacheEntry RegisterPostEvictionCallback( this ICacheEntry entry, PostEvictionDelegate callback) { ThrowHelper.ThrowIfNull(callback); return(entry.RegisterPostEvictionCallback(callback, state: null)); }
/// <summary> /// The given callback will be fired after the cache entry is evicted from the cache. /// </summary> /// <param name="options">The <see cref="MemoryCacheEntryOptions"/>.</param> /// <param name="callback">The callback to register for calling after an entry is evicted.</param> /// <returns>The <see cref="MemoryCacheEntryOptions"/> so that additional calls can be chained.</returns> public static MemoryCacheEntryOptions RegisterPostEvictionCallback( this MemoryCacheEntryOptions options, PostEvictionDelegate callback) { ThrowHelper.ThrowIfNull(callback); return(options.RegisterPostEvictionCallback(callback, state: null)); }
/// <summary> /// The given callback will be fired after the cache entry is evicted from the cache. /// </summary> /// <param name="entry"></param> /// <param name="callback"></param> public static ICacheEntry RegisterPostEvictionCallback( this ICacheEntry entry, PostEvictionDelegate callback) { if (callback == null) { throw new ArgumentNullException(nameof(callback)); } return(entry.RegisterPostEvictionCallback(callback, state: null)); }
/// <summary> /// The given callback will be fired after the cache entry is evicted from the cache. /// </summary> /// <param name="options"></param> /// <param name="callback"></param> /// <param name="state"></param> public static MemoryCacheEntryOptions RegisterPostEvictionCallback( this MemoryCacheEntryOptions options, PostEvictionDelegate callback) { if (callback == null) { throw new ArgumentNullException(nameof(callback)); } return(options.RegisterPostEvictionCallback(callback, state: null)); }
public ImagesCachingService(IMemoryCache cache) { _memoryCache = cache; _callback = (key, value, reason, state) => { var imageEntry = value as ImageCacheEntry; this.RemoveImageFromFolder(imageEntry); }; }
/// <summary> /// The given callback will be fired after the cache entry is evicted from the cache. /// </summary> /// <param name="entry">The <see cref="ICacheEntry{TKey}"/>.</param> /// <param name="callback">The callback to run after the entry is evicted.</param> /// <returns>The <see cref="ICacheEntry{TKey}"/> for chaining.</returns> public static ICacheEntry <TKey> RegisterPostEvictionCallback <TKey>( this ICacheEntry <TKey> entry, PostEvictionDelegate <TKey> callback) where TKey : notnull { if (callback == null) { throw new ArgumentNullException(nameof(callback)); } return(entry.RegisterPostEvictionCallback(callback, state: null)); }
/// <summary> /// The given callback will be fired after the cache entry is evicted from the cache. /// </summary> /// <param name="options">The <see cref="MemoryCacheEntryOptions{TKey}"/>.</param> /// <param name="callback">The callback to register for calling after an entry is evicted.</param> /// <returns>The <see cref="MemoryCacheEntryOptions{TKey}"/> so that additional calls can be chained.</returns> public static MemoryCacheEntryOptions <TKey> RegisterPostEvictionCallback <TKey>( this MemoryCacheEntryOptions <TKey> options, PostEvictionDelegate <TKey> callback) where TKey : notnull { if (callback == null) { throw new ArgumentNullException(nameof(callback)); } return(options.RegisterPostEvictionCallback(callback, state: null)); }
/// <summary> /// The given callback will be fired after the cache entry is evicted from the cache. /// </summary> /// <param name="options"></param> /// <param name="callback"></param> /// <param name="state"></param> public static MemoryCacheEntryOptions RegisterPostEvictionCallback( this MemoryCacheEntryOptions options, [NotNull] PostEvictionDelegate callback, object state) { options.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration() { EvictionCallback = callback, State = state }); return(options); }
/// <summary> /// 对单个插件进行状态监视 /// </summary> /// <param name="pluginDir"></param> private static void ListenSinglePlugin(string pluginDir) { if (!Directory.Exists(pluginDir)) { Logger.Info(string.Format("pluginDir not Exists {0} ", pluginDir)); return; } string cacheBinFileFullPath = Path.Combine(pluginDir, _load_plugins_completed_token); PostEvictionDelegate handler = null; handler = (key, valueNew, reason, state) => { try { Logger.Info(string.Format("plugin cache file {0} has changed and the plugins reload!", cacheBinFileFullPath)); //移除上次监视 ConfigHelper.MonitorConfingSnapshot.Remove(key); //强制刷新当前插件,并进行下次的监视 var pluginFiles = new DirectoryInfo(pluginDir) .EnumerateFiles(PluginConstant.PluginFileNameFormat, SearchOption.TopDirectoryOnly);//查询插件格式的dll; if (pluginFiles.IsNotEmpty()) { foreach (var assFile in pluginFiles) { var ass = Assembly.LoadFrom(assFile.FullName); var typeFinder = new AppDomainTypeFinder(); var lstPluginTypes = typeFinder.FindClassesOfType(_PluginType, new Assembly[] { ass }, true); if (lstPluginTypes.IsNotEmpty()) { foreach (var itemType in lstPluginTypes) { try { CreatePluginInstance(itemType); } catch (Exception ex) { Logger.Error(ex); } } } } } } catch (Exception ex) { Logger.Error(ex); } }; //监控插件变更 ListenFileChanged(cacheBinFileFullPath, handler); }
/// <summary> /// The given callback will be fired after the cache entry is evicted from the cache. /// </summary> /// <param name="options">The <see cref="MemoryCacheEntryOptions"/>.</param> /// <param name="callback">The callback to register for calling after an entry is evicted.</param> /// <param name="state">The state to pass to the callback.</param> /// <returns>The <see cref="MemoryCacheEntryOptions"/> so that additional calls can be chained.</returns> public static MemoryCacheEntryOptions RegisterPostEvictionCallback( this MemoryCacheEntryOptions options, PostEvictionDelegate callback, object?state) { ThrowHelper.ThrowIfNull(callback); options.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration() { EvictionCallback = callback, State = state }); return(options); }
/// <summary> /// The given callback will be fired after the cache entry is evicted from the cache. /// </summary> /// <param name="entry">The <see cref="ICacheEntry"/>.</param> /// <param name="callback">The callback to run after the entry is evicted.</param> /// <param name="state">The state to pass to the post-eviction callback.</param> /// <returns>The <see cref="ICacheEntry"/> for chaining.</returns> public static ICacheEntry RegisterPostEvictionCallback( this ICacheEntry entry, PostEvictionDelegate callback, object?state) { ThrowHelper.ThrowIfNull(callback); entry.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration() { EvictionCallback = callback, State = state }); return(entry); }
private static void ListenFileChanged(string cacheBinPath, PostEvictionDelegate callBackHandler) { //创建标识文件 if (!File.Exists(cacheBinPath)) { File.WriteAllText(cacheBinPath, DateTime.Now.ToString(), Encoding.UTF8); } FileCacheDependency dependency = new FileCacheDependency(cacheBinPath); string snapshotKey = string.Concat("plugin_listen:", cacheBinPath); var value = DateTime.Now; ConfigHelper.MonitorConfingSnapshot.Set(snapshotKey, value, dependency, callBackHandler); }
/// <summary> /// The given callback will be fired after the cache entry is evicted from the cache. /// </summary> /// <param name="entry"></param> /// <param name="callback"></param> /// <param name="state"></param> public static ICacheEntry RegisterPostEvictionCallback( this ICacheEntry entry, PostEvictionDelegate callback, object state) { if (callback == null) { throw new ArgumentNullException(nameof(callback)); } entry.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration() { EvictionCallback = callback, State = state }); return(entry); }
/// <summary> /// The given callback will be fired after the cache entry is evicted from the cache. /// </summary> /// <param name="options"></param> /// <param name="callback"></param> /// <param name="state"></param> public static MemoryCacheEntryOptions RegisterPostEvictionCallback( this MemoryCacheEntryOptions options, PostEvictionDelegate callback, object state) { if (callback == null) { throw new ArgumentNullException(nameof(callback)); } options.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration() { EvictionCallback = callback, State = state }); return(options); }
/// <summary> /// The given callback will be fired after the cache entry is evicted from the cache. /// </summary> /// <param name="entry">The <see cref="ICacheEntry{TKey}"/>.</param> /// <param name="callback">The callback to run after the entry is evicted.</param> /// <param name="state">The state to pass to the post-eviction callback.</param> /// <returns>The <see cref="ICacheEntry{TKey}"/> for chaining.</returns> public static ICacheEntry <TKey> RegisterPostEvictionCallback <TKey>( this ICacheEntry <TKey> entry, PostEvictionDelegate <TKey> callback, object?state) where TKey : notnull { if (callback == null) { throw new ArgumentNullException(nameof(callback)); } entry.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration <TKey>() { EvictionCallback = callback, State = state }); return(entry); }
/// <summary> /// The given callback will be fired after the cache entry is evicted from the cache. /// </summary> /// <param name="options">The <see cref="MemoryCacheEntryOptions{TKey}"/>.</param> /// <param name="callback">The callback to register for calling after an entry is evicted.</param> /// <param name="state">The state to pass to the callback.</param> /// <returns>The <see cref="MemoryCacheEntryOptions{TKey}"/> so that additional calls can be chained.</returns> public static MemoryCacheEntryOptions <TKey> RegisterPostEvictionCallback <TKey>( this MemoryCacheEntryOptions <TKey> options, PostEvictionDelegate <TKey> callback, object?state) where TKey : notnull { if (callback == null) { throw new ArgumentNullException(nameof(callback)); } options.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration <TKey>() { EvictionCallback = callback, State = state }); return(options); }
/// <summary> /// 向内存缓存对象中插入一条记录,并基于文件依赖 /// </summary> /// <typeparam name="TItem"></typeparam> /// <param name="cache"></param> /// <param name="key"></param> /// <param name="value"></param> /// <param name="dependency"></param> /// <param name="callbackHandler"></param> public static void Set <T>(this IMemoryCache cache, string key, T value, FileCacheDependency dependency, PostEvictionDelegate callbackHandler = null ) { var fileInfo = new FileInfo(dependency.FilePath); var fileProvider = new PhysicalFileProvider(fileInfo.DirectoryName); var options = new MemoryCacheEntryOptions() .AddExpirationToken(fileProvider.Watch(fileInfo.Name)); if (null != callbackHandler) { //注册回调事件 options.RegisterPostEvictionCallback(callbackHandler); } cache.Set(key, value, options); }
/// <summary> /// 监视根目录下的全部插件 /// 根据根目录下的 缓存监视标志文件的变更,进行事件监视 /// </summary> private static void ListenGlobleRootPlugin() { string cacheBinFileFullPath = Path.Combine(PluginRootDir, _load_plugins_completed_token); PostEvictionDelegate handler = null; handler = (key, valueNew, reason, state) => { try { Logger.Info(string.Format("plugin cache file {0} has changed and the plugins reload!", cacheBinFileFullPath)); //移除上次监视 ConfigHelper.MonitorConfingSnapshot.Remove(key); //强制刷新插件,并进行下次的监视 PluginManager.AutoDiscoverPlugins(); } catch (Exception ex) { Logger.Error(ex); } }; //监控插件变更 ListenFileChanged(cacheBinFileFullPath, handler); }
/// <summary> /// The given callback will be fired after the cache entry is evicted from the cache. /// </summary> /// <param name="options"></param> /// <param name="callback"></param> /// <param name="state"></param> public static MemoryCacheEntryOptions RegisterPostEvictionCallback( this MemoryCacheEntryOptions options, PostEvictionDelegate callback) { if (callback == null) { throw new ArgumentNullException(nameof(callback)); } return options.RegisterPostEvictionCallback(callback, state: null); }
/// <summary> /// 从自定义的配置文件目录加载配置 /Configs 目录下的配置文件 /// 系统默认的配置文件 appsettings.json 会跟随系统的DI 过来 /// </summary> /// <param name="configFileName">json 文件名称</param> /// <param name="args">命令参数</param> /// <param name="isReloadOnChange">文件变更的时候,是否自动重新加载</param> /// <returns></returns> public static IConfiguration GetCustomConfiguration(string configFileName, string[] args = null, bool isReloadOnChange = true) { string configDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Configs"); string configFileFullPath = Path.Combine(configDir, configFileName); if (!File.Exists(configFileFullPath)) { throw new FileNotFoundException(string.Format("the config file : {0} is not be found.", configFileFullPath)); } var config = new ConfigurationBuilder() .SetBasePath(configDir) .AddJsonFile(configFileName, optional: true, reloadOnChange: isReloadOnChange) .AddEnvironmentVariables(prefix: "ASPNETCORE_"); if (null != args) { config.AddCommandLine(args); } var configRoot = config.Build(); if (true == isReloadOnChange) { //如果设置为自动 加载,当变更的时候,会产生一个 IOptionsSnapshot 快照对象 //但是这种强类型刷新快照按照官方的说法是基于DI 的方式,感觉找不到北,我们利用注册回调事件处理 FileCacheDependency dependency = new FileCacheDependency(configFileFullPath); string snapshotKey = string.Concat("__Snapshot_Config_", configFileName); var value = DateTime.Now; PostEvictionDelegate handler = null; handler = (key, valueNew, reason, state) => { try { //强制刷新配置 configRoot.Reload(); //重新设定新的值 并从新插入到缓存中进行监听 value = DateTime.Now; MonitorConfingSnapshot.Set(snapshotKey, value, dependency, handler); //通知订阅的事件触发 if (configRoot == AppSettingsConfiguration && null != OnHostingConfigChangedEvent) { OnHostingConfigChangedEvent.Invoke("ConfigHelper", new ConfigChangedEventArgs { ResultOfChangedConfig = configRoot }); } Logger.Info(string.Format("config file {0} has changed and the config object at application has reload!", configFileFullPath)); } catch (Exception ex) { throw new Exception(string.Format("can not Reload ConfigRoot! Error is:{0}", ex.ToString())); } }; MonitorConfingSnapshot.Set(snapshotKey, value, dependency, handler); } return(configRoot); }
private void AddEvictionTracker(string key, object item, TimeSpan expirationSpan, PostEvictionDelegate callback) { if (expirationSpan > TimeSpan.Zero) { var cache = ExpirationTrackingCache; var options = new MemoryCacheEntryOptions() { //AbsoluteExpiration = absoluteExpiration, AbsoluteExpirationRelativeToNow = expirationSpan }; var callbackRegistration = new PostEvictionCallbackRegistration(); callbackRegistration.EvictionCallback = callback; callbackRegistration.State = key; options.PostEvictionCallbacks.Add(callbackRegistration); cache.Set(key, new object(), options); } }
/// <summary> /// The given callback will be fired after the cache entry is evicted from the cache. /// </summary> /// <param name="options"></param> /// <param name="callback"></param> /// <param name="state"></param> public static MemoryCacheEntryOptions RegisterPostEvictionCallback( this MemoryCacheEntryOptions options, [NotNull] PostEvictionDelegate callback) { return(options.RegisterPostEvictionCallback(callback, state: null)); }
/// <summary> /// The given callback will be fired after the cache entry is evicted from the cache. /// </summary> /// <param name="options"></param> /// <param name="callback"></param> /// <param name="state"></param> public static MemoryCacheEntryOptions RegisterPostEvictionCallback( this MemoryCacheEntryOptions options, PostEvictionDelegate callback, object state) { if (callback == null) { throw new ArgumentNullException(nameof(callback)); } options.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration() { EvictionCallback = callback, State = state }); return options; }