威尼斯wns.9778官网活动_vnsc威尼斯城官网

热门关键词: 威尼斯wns.9778官网活动,vnsc威尼斯城官网
当前位置:威尼斯wns.9778官网活动 > 计算机教程 > 【威尼斯wns.9778官网活动】在.NET项目中使用Post

【威尼斯wns.9778官网活动】在.NET项目中使用Post

文章作者:计算机教程 上传时间:2019-05-10

在之前一篇随笔《在.NET项目中使用PostSharp,实现AOP面向切面编程处理》介绍了PostSharp框架的使用,使用PostSharp能给我带来很多便利和优势,减少代码冗余,提高可读性,并且可以更加优雅的实现常规的日志、异常、缓存、事务等业务场景的处理。本篇主要介绍使用MemoryCache实现缓存的处理。

在.NET项目中使用PostSharp,使用MemoryCache实现缓存的处理,memorycache缓存原理

在之前一篇随笔《在.NET项目中使用PostSharp,实现AOP面向切面编程处理》介绍了PostSharp框架的使用,试用PostSharp能给我带来很多便利和优势,减少代码冗余,提高可读性,并且可以更加优雅的实现常规的日志、异常、缓存、事务等业务场景的处理。本篇主要介绍使用MemoryCache实现缓存的处理。

1、MemoryCache的介绍回顾

上篇没有提及缓存的处理,一般情况下,缓存的处理我们可以利用微软的分布式缓存组件MemoryCache进行缓存的处理操作。MemoryCache的使用网上介绍的不多,不过这个是.NET4.0新引入的缓存对象,主要是替换原来企业库的缓存模块,使得.NET的缓存可以无处不在,而不用基于特定的Windows版本上使用。

缓存在很多情况下需要用到,合理利用缓存可以一方面可以提高程序的响应速度,同时可以减少对特定资源访问的压力。本文主要针对自己在Winform方面的缓存使用做一个引导性的介绍,希望大家能够从中了解一些缓存的使用场景和使用方法。缓存是一个中大型系统所必须考虑的问题。为了避免每次请求都去访问后台的资源(例如数据库),我们一般会考虑将一些更新不是很频繁的,可以重用的数据,通过一定的方式临时地保存起来,后续的请求根据情况可以直接访问这些保存起来的数据。这种机制就是所谓的缓存机制。

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

System.Runtime.Caching这是在.NET 4.0中新增的缓存框架,主要是使用MemoryCache对象,该对象存在于程序集System.Runtime.Caching.dll。

System.Web.Caching.Cache这个则是在.NET2.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来做做缓存

我在之前的一篇随笔《Winform里面的缓存使用》曾经介绍了MemoryCache辅助类的处理,用来方便实现缓存的数据操作。它的辅助类主要代码如下所示。

    /// <summary>
    /// 基于MemoryCache的缓存辅助类
    /// </summary>
    public static class MemoryCacheHelper
    {
        private static readonly Object locker = new object();

        /// <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 GetCacheItem<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(locker)
                {
                    if(MemoryCache.Default[key] == null)
                    {
                        var item = new CacheItem(key, cachePopulate());
                        var policy = CreatePolicy(slidingExpiration, absoluteExpiration);

                        MemoryCache.Default.Add(item, policy);
                    }
                }
            }

            return (T)MemoryCache.Default[key];
        }

        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>
        public static void ClearCache()
        {
            List<string> cacheKeys = MemoryCache.Default.Select(kvp => kvp.Key).ToList();
            foreach (string cacheKey in cacheKeys)
            {
                MemoryCache.Default.Remove(cacheKey);
            }
        }

      ...//省略部分代码

    }

而我们在程序中,如果需要使用缓存,那么调用这个辅助类来解决,也算是比较方便的,实现缓存的代码如下所示。

    public static class UserCacheService
    {
        /// <summary>
        /// 获取用户全部简单对象信息,并放到缓存里面
        /// </summary>
        /// <returns></returns>
        public static List<SimpleUserInfo> GetSimpleUsers()
        {
            System.Reflection.MethodBase method = System.Reflection.MethodBase.GetCurrentMethod();
            string key = string.Format("{0}-{1}", method.DeclaringType.FullName, method.Name);

            return MemoryCacheHelper.GetCacheItem<List<SimpleUserInfo>>(key,
                delegate() {
                    //return CallerFactory<IUserService>.Instance.GetSimpleUsers(); 

                    //模拟从数据库获取数据
                    List<SimpleUserInfo> list = new List<SimpleUserInfo>();
                    for(int i = 0; i< 10; i  )
                    {
                        var info = new SimpleUserInfo();
                        info.ID = i;
                        info.Name = string.Concat("Name:", i);
                        info.FullName = string.Concat("姓名:", i);
                        list.Add(info);
                    }
                    return list;
                },
                new TimeSpan(0, 10, 0));//10分钟过期
        }

        /// <summary>
        /// 根据用户的ID,获取用户的登陆名称,并放到缓存里面
        /// </summary>
        /// <param name="userId">用户的ID</param>
        /// <returns></returns>
        public static string GetNameByID(string userId)
        {
            string result = "";
            if (!string.IsNullOrEmpty(userId))
            {
                System.Reflection.MethodBase method = System.Reflection.MethodBase.GetCurrentMethod();
                string key = string.Format("{0}-{1}-{2}", method.DeclaringType.FullName, method.Name, userId);

                result = MemoryCacheHelper.GetCacheItem<string>(key,
                    delegate() {
                        //return CallerFactory<IUserService>.Instance.GetNameByID(userId.ToInt32()); 

                        return string.Concat("Name:", userId);
                    },
                    new TimeSpan(0, 30, 0));//30分钟过期
            }
            return result;
        }

上面案例我模拟构造数据库数据返回,否则一般使用BLLFactory<T>、或者混合框架客户端里面使用CallerFactory<T>进行调用接口了,相当于需要对它们进行进一步的函数封装处理才能达到目的。

威尼斯wns.9778官网活动,案例中可以设置失效缓存时间,并且失效后,自动通过Func<T> cachePopulate的函数重新获取缓存内容,在实际情况下,也是非常智能的一种处理方式。

1、MemoryCache的介绍回顾

上篇没有提及缓存的处理,一般情况下,缓存的处理我们可以利用微软的分布式缓存组件MemoryCache进行缓存的处理操作。MemoryCache的使用网上介绍的不多,不过这个是.NET4.0新引入的缓存对象,主要是替换原来企业库的缓存模块,使得.NET的缓存可以无处不在,而不用基于特定的Windows版本上使用。

缓存在很多情况下需要用到,合理利用缓存可以一方面可以提高程序的响应速度,同时可以减少对特定资源访问的压力。本文主要针对自己在Winform方面的缓存使用做一个引导性的介绍,希望大家能够从中了解一些缓存的使用场景和使用方法。缓存是一个中大型系统所必须考虑的问题。为了避免每次请求都去访问后台的资源(例如数据库),我们一般会考虑将一些更新不是很频繁的,可以重用的数据,通过一定的方式临时地保存起来,后续的请求根据情况可以直接访问这些保存起来的数据。这种机制就是所谓的缓存机制。

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

System.Runtime.Caching这是在.NET 4.0中新增的缓存框架,主要是使用MemoryCache对象,该对象存在于程序集System.Runtime.Caching.dll。

System.Web.Caching.Cache这个则是在.NET2.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来做做缓存

我在之前的一篇随笔《Winform里面的缓存使用》曾经介绍了MemoryCache辅助类的处理,用来方便实现缓存的数据操作。它的辅助类主要代码如下所示。

    /// <summary>
    /// 基于MemoryCache的缓存辅助类
    /// </summary>
    public static class MemoryCacheHelper
    {
        private static readonly Object locker = new object();

        /// <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 GetCacheItem<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(locker)
                {
                    if(MemoryCache.Default[key] == null)
                    {
                        var item = new CacheItem(key, cachePopulate());
                        var policy = CreatePolicy(slidingExpiration, absoluteExpiration);

                        MemoryCache.Default.Add(item, policy);
                    }
                }
            }

            return (T)MemoryCache.Default[key];
        }

        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>
        public static void ClearCache()
        {
            List<string> cacheKeys = MemoryCache.Default.Select(kvp => kvp.Key).ToList();
            foreach (string cacheKey in cacheKeys)
            {
                MemoryCache.Default.Remove(cacheKey);
            }
        }

      ...//省略部分代码

    }

而我们在程序中,如果需要使用缓存,那么调用这个辅助类来解决,也算是比较方便的,实现缓存的代码如下所示。

    public static class UserCacheService
    {
        /// <summary>
        /// 获取用户全部简单对象信息,并放到缓存里面
        /// </summary>
        /// <returns></returns>
        public static List<SimpleUserInfo> GetSimpleUsers()
        {
            System.Reflection.MethodBase method = System.Reflection.MethodBase.GetCurrentMethod();
            string key = string.Format("{0}-{1}", method.DeclaringType.FullName, method.Name);

            return MemoryCacheHelper.GetCacheItem<List<SimpleUserInfo>>(key,
                delegate() {
                    //return CallerFactory<IUserService>.Instance.GetSimpleUsers(); 

                    //模拟从数据库获取数据
                    List<SimpleUserInfo> list = new List<SimpleUserInfo>();
                    for(int i = 0; i< 10; i  )
                    {
                        var info = new SimpleUserInfo();
                        info.ID = i;
                        info.Name = string.Concat("Name:", i);
                        info.FullName = string.Concat("姓名:", i);
                        list.Add(info);
                    }
                    return list;
                },
                new TimeSpan(0, 10, 0));//10分钟过期
        }

        /// <summary>
        /// 根据用户的ID,获取用户的登陆名称,并放到缓存里面
        /// </summary>
        /// <param name="userId">用户的ID</param>
        /// <returns></returns>
        public static string GetNameByID(string userId)
        {
            string result = "";
            if (!string.IsNullOrEmpty(userId))
            {
                System.Reflection.MethodBase method = System.Reflection.MethodBase.GetCurrentMethod();
                string key = string.Format("{0}-{1}-{2}", method.DeclaringType.FullName, method.Name, userId);

                result = MemoryCacheHelper.GetCacheItem<string>(key,
                    delegate() {
                        //return CallerFactory<IUserService>.Instance.GetNameByID(userId.ToInt32()); 

                        return string.Concat("Name:", userId);
                    },
                    new TimeSpan(0, 30, 0));//30分钟过期
            }
            return result;
        }

上面案例我模拟构造数据库数据返回,否则一般使用BLLFactory<T>、或者混合框架客户端里面使用CallerFactory<T>进行调用接口了,相当于需要对它们进行进一步的函数封装处理才能达到目的。

案例中可以设置失效缓存时间,并且失效后,自动通过Func<T> cachePopulate的函数重新获取缓存内容,在实际情况下,也是非常智能的一种处理方式。

本文由威尼斯wns.9778官网活动发布于计算机教程,转载请注明出处:【威尼斯wns.9778官网活动】在.NET项目中使用Post

关键词: