很多情况下需要用到缓存,合理利用缓存一方面可以提高程序的响应速度,同时可以减少对特定资源访问的压力。为了避免每次请求都去访问后台的

资源(例如数据库),一般会考虑将一些更新不是很频繁的、可以重用的数据,通过一定的方式临时地保存起来,后续的请求根据情况可以直接访问这

些保存起来的数据,这种机制就是所谓的缓存机制。

.NET 4.0的缓存功能主要由三部分组成:System.Runtime.Caching,System.Web.Caching.Cache和Output Cache。

MemoryCache:这个是在.NET 4.0中新增的缓存框架,Namespace:System.Runtime.Caching ,Assembly:System.Runtime.Caching.dll。

System.Web.Caching.Cache:这个是在.NET 2.0开始就一直存在的缓存对象,一般主要用在Web中,当然也可以用于Winform里面,不过要引用

System.Web.dll。

Output Cache:这个是在Asp.NET里面使用的。在ASP.NET 4.0之前,都是直接使用System.Web.Caching.Cache来缓存HTML片段。在ASP.NET 4.0

中对它进行了重新设计,提供了一个OutputCacheProvider供开发人员进行扩展,但是它默认情况下,仍然使用System.Web.Caching.Cache来做做缓存。

下面演示MemoryCache的简单使用:

1、添加一个类,命名为ConfigHelper,代码如下:

    /// <summary>
/// 配置帮助类
/// </summary>
class ConfigHelper
{
/// <summary>
/// 获取管理配置文件对象
/// </summary>
/// <param name="configPath">指定要管理的配置文件路径,如果为空或不存在,则为管理程序集默认的配置文件路径。</param>
/// <returns></returns>
private static Configuration GetConfiguration(string configPath = null)
{
if (!string.IsNullOrEmpty(configPath) && File.Exists(configPath))
{
ExeConfigurationFileMap map = new ExeConfigurationFileMap
{
ExeConfigFilename = configPath
};
return ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
}
else
{
return ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
}
} /// <summary>
/// 获取指定配置文件+配置名称的配置项的值
/// </summary>
public static string GetAppSettingValue(string key, string defaultValue = null, string configPath = null)
{
var config = GetConfiguration(configPath);
var appSetting = config.AppSettings.Settings[key];
return appSetting.Value;
} /// <summary>
/// 获取所有配置值
/// </summary>
public static Dictionary<string, string> GetAppSettingValues(string configPath = null)
{
Dictionary<string, string> settingDic = new Dictionary<string, string>();
var config = GetConfiguration(configPath);
var settings = config.AppSettings.Settings;
foreach (string key in settings.AllKeys)
{
settingDic[key] = settings[key].ToString();
}
return settingDic;
} /// <summary>
/// 设置配置值(存在则更新,不存在则新增。)
/// </summary>
public static void SetAppSettingValue(string key, string value, string configPath = null)
{
var config = GetConfiguration(configPath);
var setting = config.AppSettings.Settings[key];
if (setting == null)
{
config.AppSettings.Settings.Add(key, value);
}
else
{
setting.Value = value;
} config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
} /// <summary>
/// 设置多个配置值(存在则更新,不存在则新增)
/// </summary>
public static void SetAppSettingValues(IEnumerable<KeyValuePair<string, string>> settingValues, string configPath = null)
{
var config = GetConfiguration(configPath);
foreach (var item in settingValues)
{
var setting = config.AppSettings.Settings[item.Key];
if (setting == null)
{
config.AppSettings.Settings.Add(item.Key, item.Value);
}
else
{
setting.Value = item.Value;
}
}
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
} /// <summary>
/// 删除配置值
/// </summary>
public static void RemoveAppSetting(string key, string configPath = null)
{
var config = GetConfiguration(configPath);
config.AppSettings.Settings.Remove(key);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
} /// <summary>
/// 删除多个配置值
/// </summary>
public static void RemoveAppSettings(string configPath = null, params string[] keys)
{
var config = GetConfiguration(configPath);
if (keys != null)
{
foreach (string key in keys)
{
config.AppSettings.Settings.Remove(key);
}
}
else
{
config.AppSettings.Settings.Clear();
}
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
} /// <summary>
/// 获取连接字符串
/// </summary>
public static string GetConnectionString(string name, string defaultconnString = null, string configPath = null)
{
var config = GetConfiguration(configPath);
var connStringSettings = config.ConnectionStrings.ConnectionStrings[name];
if (connStringSettings == null)
{
return defaultconnString;
}
return connStringSettings.ConnectionString;
} /// <summary>
/// 获取指定配置文件+连接名称的连接字符串配置项
/// </summary>
public static ConnectionStringSettings GetConnectionStringSetting(string name, string configPath = null)
{
var config = GetConfiguration(configPath);
var connStringSettings = config.ConnectionStrings.ConnectionStrings[name];
return connStringSettings;
} /// <summary>
/// 获取所有的连接字符串配置项
/// </summary>
public static Dictionary<string, ConnectionStringSettings> GetConnectionStringSettings(string configPath = null)
{
var config = GetConfiguration(configPath);
var connStringSettingDic = new Dictionary<string, ConnectionStringSettings>();
var connStringSettings = ConfigurationManager.ConnectionStrings;
foreach (ConnectionStringSettings item in connStringSettings)
{
connStringSettingDic[item.Name] = item;
}
return connStringSettingDic;
} /// <summary>
/// 设置连接字符串的值(存在则更新,不存在则新增。)
/// </summary>
public static void SetConnectionString(string name, string connString, string provider, string configPath = null)
{
var config = GetConfiguration(configPath);
ConnectionStringSettings connStringSettings = config.ConnectionStrings.ConnectionStrings[name];
if (connStringSettings != null)
{
connStringSettings.ConnectionString = connString;
connStringSettings.ProviderName = provider;
}
else
{
connStringSettings = new ConnectionStringSettings(name, connString, provider);
config.ConnectionStrings.ConnectionStrings.Add(connStringSettings);
} config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("connectionStrings");
} /// <summary>
/// 设置多个连接字符串的值(存在则更新,不存在则新增。)
/// </summary>
public static void SetConnectionStrings(IEnumerable<ConnectionStringSettings> connStringSettings, string configPath = null)
{
var config = GetConfiguration(configPath);
foreach (var item in connStringSettings)
{
ConnectionStringSettings connStringSetting = config.ConnectionStrings.ConnectionStrings[item.Name];
if (connStringSetting != null)
{
connStringSetting.ConnectionString = item.ConnectionString;
connStringSetting.ProviderName = item.ProviderName;
}
else
{
config.ConnectionStrings.ConnectionStrings.Add(item);
}
} config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("connectionStrings");
} /// <summary>
/// 删除连接字符串配置项
/// </summary>
public static void RemoveConnectionString(string name, string configPath = null)
{
var config = GetConfiguration(configPath);
config.ConnectionStrings.ConnectionStrings.Remove(name);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("connectionStrings");
} /// <summary>
/// 删除多个连接字符串配置项
/// </summary>
public static void RemoveConnectionStrings(string configPath = null, params string[] names)
{
var config = GetConfiguration(configPath);
if (names != null)
{
foreach (string name in names)
{
config.ConnectionStrings.ConnectionStrings.Remove(name);
}
}
else
{
config.ConnectionStrings.ConnectionStrings.Clear();
}
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("connectionStrings");
}
}

2、添加一个类,命名为MemoryCacheHelper(注意需引用System.Runtime.Caching.dll),代码如下:

    /// <summary>
/// 内存缓存帮助类,支持绝对过期时间、滑动过期时间、文件依赖三种缓存方式。
/// </summary>
class MemoryCacheHelper
{
private static readonly object _locker1 = new object(), _locker2 = new object(); /// <summary>
/// 取缓存项,如果不存在则返回空。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public static T GetCacheItem<T>(string key)
{
try
{
return (T)MemoryCache.Default[key];
}
catch
{
return default(T);
}
} /// <summary>
/// 是否包含指定键的缓存项
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static bool Contains(string key)
{
return MemoryCache.Default.Contains(key);
} /// <summary>
/// 取缓存项,如果不存在则新增缓存项。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="cachePopulate"></param>
/// <param name="slidingExpiration"></param>
/// <param name="absoluteExpiration"></param>
/// <returns></returns>
public static T GetOrAddCacheItem<T>(string key, Func<T> cachePopulate, TimeSpan? slidingExpiration = null, DateTime? absoluteExpiration = null)
{
if (string.IsNullOrWhiteSpace(key)) throw new ArgumentException("Invalid cache key");
if (cachePopulate == null) throw new ArgumentNullException("cachePopulate");
if (slidingExpiration == null && absoluteExpiration == null) throw new ArgumentException("Either a sliding expiration or absolute must be provided"); if (MemoryCache.Default[key] == null)
{
lock (_locker1)
{
if (MemoryCache.Default[key] == null)
{
T cacheValue = cachePopulate();
if (!typeof(T).IsValueType && cacheValue == null) //如果是引用类型且为NULL则不存缓存
{
return cacheValue;
} var item = new CacheItem(key, cacheValue);
var policy = CreatePolicy(slidingExpiration, absoluteExpiration); MemoryCache.Default.Add(item, policy);
}
}
} return (T)MemoryCache.Default[key];
} /// <summary>
/// 取缓存项,如果不存在则新增缓存项。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="cachePopulate"></param>
/// <param name="dependencyFilePath"></param>
/// <returns></returns>
public static T GetOrAddCacheItem<T>(string key, Func<T> cachePopulate, string dependencyFilePath)
{
if (string.IsNullOrWhiteSpace(key)) throw new ArgumentException("Invalid cache key");
if (cachePopulate == null) throw new ArgumentNullException("cachePopulate"); if (MemoryCache.Default[key] == null)
{
lock (_locker2)
{
if (MemoryCache.Default[key] == null)
{
T cacheValue = cachePopulate();
if (!typeof(T).IsValueType && cacheValue == null) //如果是引用类型且为NULL则不存缓存
{
return cacheValue;
} var item = new CacheItem(key, cacheValue);
var policy = CreatePolicy(dependencyFilePath); MemoryCache.Default.Add(item, policy);
}
}
} return (T)MemoryCache.Default[key];
} /// <summary>
/// 指定缓存项的一组逐出和过期详细信息
/// </summary>
/// <param name="slidingExpiration"></param>
/// <param name="absoluteExpiration"></param>
/// <returns></returns>
private static CacheItemPolicy CreatePolicy(TimeSpan? slidingExpiration, DateTime? absoluteExpiration)
{
var policy = new CacheItemPolicy(); if (absoluteExpiration.HasValue)
{
policy.AbsoluteExpiration = absoluteExpiration.Value;
}
else if (slidingExpiration.HasValue)
{
policy.SlidingExpiration = slidingExpiration.Value;
} policy.Priority = CacheItemPriority.Default; return policy;
} /// <summary>
/// 指定缓存项的一组逐出和过期详细信息
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
private static CacheItemPolicy CreatePolicy(string filePath)
{
CacheItemPolicy policy = new CacheItemPolicy();
policy.ChangeMonitors.Add(new HostFileChangeMonitor(new List<string>() { filePath }));
policy.Priority = CacheItemPriority.Default;
return policy;
} /// <summary>
/// 移除指定键的缓存项
/// </summary>
/// <param name="key"></param>
public static void RemoveCacheItem(string key)
{
if (Contains(key))
{
MemoryCache.Default.Remove(key);
}
}
}

3、添加一个WinForm窗体,命名为Main,并添加一个按钮。

4、配置App.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<connectionStrings>
<add name ="connString" connectionString="server=.;database=db_test;uid=sa;pwd=********;" />
</connectionStrings>
</configuration>

5、Main窗体代码如下:

        private void button1_Click(object sender, EventArgs e)
{
int times1 = , times2 = ;
for (int i = ; i < ; i++)
{
if (MemoryCacheHelper.Contains("connString"))
{
times1++;
}
else
{
times2++;
string connstr = MemoryCacheHelper.GetOrAddCacheItem("connString", () =>
{
return ConfigHelper.GetConnectionString("connString", null);
}, Application.StartupPath + @"\App.config");
}
}
MessageBox.Show($"内存缓存读取次数:{times1},非内存缓存读取次数:{times2}", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}

6、运行结果如下:

参考自:

https://www.cnblogs.com/mq0036/p/10312945.html

https://www.cnblogs.com/zuowj/p/8366735.html

https://www.cnblogs.com/zuowj/p/8440902.html

C# MemoryCache学习笔记的更多相关文章

  1. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  2. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  3. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  4. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  5. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  6. seaJs学习笔记2 – seaJs组建库的使用

    原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...

  7. CSS学习笔记

    CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...

  8. HTML学习笔记

    HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...

  9. DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记

    今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...

随机推荐

  1. Mysql 8+ 版本完全踩坑记录

    问题是这样 刚霍霍了一台腾讯云服务器需要安装mysql 然后就选择了8+这个版本. 安装步骤网上有的是. 我只写最主要的部分 绝对不出错 外网可访问 .net java都可以调用 其实不指望有人看 就 ...

  2. A complex 16-Level XSS Challenge

    A complex 16-Level XSS Challenge, held in summer 2014 (+1 Hidden Level) Index Level 0 Level 1 Level ...

  3. 什么是Druid

    一.Druid是什么 Druid 单词来源于西方古罗马的神话人物,中文常常翻译成德鲁伊. 玩过魔兽世界,暗黑破坏神,Dota,炉石传说,Dota自走棋的朋友,对这个词一定不陌生. 本文中所介绍的Dru ...

  4. springboot集成quartz实现任务调度

    quartz 概述 特点 强大的调度功能 灵活的应用方式 分布式和集群能力 用到的设计模式 Builder 模式 factory模式 组件模式 链式写法 体系结构 调度器 任务 触发器 架构图 spr ...

  5. geojson转esriJson

    因为一些特殊需求,需要将geojson转为shp数据,网上有一些转换网站,但是存在一些问题,例如中文乱码.文件大小限制等等,折腾了一下,还是觉得用arcgis转比较好,因此先将geojson转为esr ...

  6. 【学习笔记】Git的日常使用

    Note:本笔记是我学习廖雪峰老师的Git教程整理得到,在此向廖老师的无私付出表示衷心的感谢! 0.Git的历史 Git是一个分布式的版本控制系统(C语言编写,一开始为Linux社区服务,替代BitK ...

  7. Oracle数据库、实例、用户、表空间、表之间的关系

    完整的Oracle数据库通常由两部分组成:Oracle数据库和数据库实例. 1) 数据库是一系列物理文件的集合(数据文件,控制文件,联机日志,参数文件等): 2) Oracle数据库实例则是一组Ora ...

  8. 如何快速查看Linux日志?

    因为在生产环境会遇到很多问题,那么最快的定位方式莫过于去看日志,我们都知道服务器每天会产生大量的日志,那么如何快速的定位也就是最关键的. 本文介绍六种查看日志的命令:tail.head.cat.mor ...

  9. GetModuleFileNameEx遍历获取64bit程序路径失败的一种解决方法(Win7-64-bit)

    问题: 32位程序在64位系统上调用GetModuleFileNameEx()遍历获取64位进程的全路径失败,得到的路径都为空. 根据官方的说法: For the best results use t ...

  10. jsp简单实现交互

    test.html <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type&quo ...