zoukankan      html  css  js  c++  java
  • .net系统缓存

    .net系统缓存封装设计

    缓存管理的接口ICache,可以用来保存键值对数据,设置缓存过期时间等功能,接口设计如下:

    public interface ICache
    {
            bool IsInitialized { get; }
    
            Task<Result> InitAsync(string connStr);
    
            Task<T> GetAsync<T>(string key, Func<T> defaultFunc = null, bool setDefault = false);
    
            Task<bool> SetAsync<T>(string key, T value, int expiredSeconds = 0);
    
            Task<bool> RemoveAsync(string key);
    
            Task<bool> ExistsAsync(string key);
    
            Task<long> SAddAsync<T>(string key, params T[] members);
    
            Task<long> SCountAsync(string key);
    
            Task<T[]> SMembersAsync<T>(string key);
    
            Task<bool> SIsMemberAsync<T>(string key, T member);
    
            Task<long> SRemoveAsync<T>(string key, params T[] members);
    
            /// <summary>
            /// 设置指定Key的过期时间
            /// </summary>
            /// <param name="key">The key.</param>
            /// <param name="expiredSeconds">The expired seconds.</param>
            /// <returns>Task&lt;System.Boolean&gt;.</returns>
            Task<bool> SetExpireTimeAsync(string key, int expiredSeconds);
     }
    

    服务端缓存采用Redis实现,具体实现如下:

    internal class RedisCache : ICache
    {
            private IRedisClient _client;
    
            private void CheckValid()
            {
                if (_client == null)
                    throw new InvalidOperationException("RedisClient未初始化!");
            }
    
            public bool IsInitialized => _client != null;
    
            public async Task<Result> InitAsync(string connStr)
            {
                try
                {
                    if (_client != null)
                        return Result.Ok;
                    //connStr = "data source=127.0.0.1:6379;initial catalog=1";
                    _client = await RedisClient.ConnectAsync(connStr, new RedisJsonSerializer());
                    return Result.Ok;
                }
                catch (Exception e)
                {
                    return new Result(e, "初始化Redis客户端失败!");
                }
            }
    
            public void ClearCache()
            {
                _client?.FlushDbAsync().Wait();
            }
    
            public async Task<T> GetAsync<T>(string key, Func<T> defaultFunc = null, bool setDefault = false)
            {
                CheckValid();
                try
                {
                    var bulk = await _client.GetAsync(key);
                    if (!bulk.IsNull)
                        return bulk.As<T>();
                }
                catch
                {
                    //ignore
                }
                if (defaultFunc == null)
                    throw new KeyNotFoundException($"Redis中值为{key}的键不存在,或值不是{typeof(T)}");
                var value = defaultFunc();
                if (setDefault)
                    await SetAsync(key, value, 0);
                return value;
            }
    
            public async Task<bool> SetAsync<T>(string key, T value, int expiredSeconds)
            {
                CheckValid();
                string result;
                if (expiredSeconds > 0)
                    result = await _client.SetExAsync(key, expiredSeconds, value);
                else
                    result = await _client.SetAsync(key, value);
                return result == "OK";
            }
    
            public async Task<bool> RemoveAsync(string key)
            {
                CheckValid();
                var r = await _client.DelAsync(key);
                return r == 1;
            }
    
            public async Task<bool> ExistsAsync(string key)
            {
                CheckValid();
                var r = await _client.ExistsAsync(key);
                return r == 1;
            }
    
            public async Task<long> SAddAsync<T>(string key, params T[] members)
            {
                CheckValid();
                var r = await _client.SAddAsync(key, members);
                return r;
            }
    
            public async Task<long> SCountAsync(string key)
            {
                CheckValid();
                var r = await _client.SCardAsync(key);
                return r;
            }
    
            public async Task<T[]> SMembersAsync<T>(string key)
            {
                CheckValid();
                var r = await _client.SMembersAsync(key);
                return r.AsArray<T>();
            }
    
            public async Task<bool> SIsMemberAsync<T>(string key, T member)
            {
                CheckValid();
                var r = await _client.SIsMemberAsync(key, member);
                return r == 1;
            }
    
            public async Task<long> SRemoveAsync<T>(string key, params T[] members)
            {
                CheckValid();
                var r = await _client.SRemAsync(key, members);
                return r;
            }
    
            public async Task<long> HCountAsync(string key)
            {
                CheckValid();
                return await _client.HLenAsync(key);
            }
    
            public async Task<T> HGetAsync<T>(string key, string field, Func<T> defaultFunc = null)
            {
                CheckValid();
                var r = await _client.HExistsAsync(key, field);
                if (r == 1)
                {
                    try
                    {
                        var bulk = await _client.HGetAsync(key, field);
                        if (!bulk.IsNull)
                            return bulk.As<T>();
                    }
                    catch
                    {
                        //ignore
                    }
                }
                if (defaultFunc == null)
                    throw new KeyNotFoundException($"Redis中值为{key}-{field}的键不存在,或值不是{typeof(T)}");
                return defaultFunc();
            }
    
            public async Task HSetAsync<T>(string key, string field, T value)
            {
                CheckValid();
                await _client.HSetAsync(key, field, value);
            }
    
            public async Task<bool> HRemoveAsync(string key, string field)
            {
                CheckValid();
                var count = await _client.HDelAsync(key, field);
                return count == 1;
            }
    
            public async Task HRemoveAsync(string key, string[] fields)
            {
                CheckValid();
                await _client.HDelAsync(key, fields);
            }
    
            public async Task<bool> HExistsAsync(string key, string field)
            {
                CheckValid();
                return await _client.HExistsAsync(key, field) == 1;
            }
    
            public async Task<string[]> HKeysAsync(string key)
            {
                CheckValid();
                var bulk = await _client.HKeysAsync(key);
                return bulk.IsNull ? new string[0] : bulk.AsArray<string>();
            }
    
            public async Task<KeyValuePair<string, T>[]> HAllAsync<T>(string key)
            {
                CheckValid();
                var bulk = await _client.HGetAllAsync(key);
                if (bulk.IsNull)
                    return new KeyValuePair<string, T>[0];
                var values = bulk.AsArray<string>();
                var results = new KeyValuePair<string, T>[values.Length / 2];
                for (var i = 0; i < values.Length; i += 2)
                {
                    var k = values[i];
                    var v = values[i + 1].As<T>();
                    results[i / 2] = new KeyValuePair<string, T>(k, v);
                }
                return results;
            }
    
            public async Task<bool> SetExpireTimeAsync(string key, int expiredSeconds)
            {
                CheckValid();
                if (expiredSeconds < 0)
                    return false;
                var r = await _client.ExpireAsync(key, expiredSeconds);
                return r == 1;
            }
     }
    

    CS及MS端的缓存采用Akavache实现,具体实现如下:

    internal partial class Cache : ICache
    {
    		public bool IsInitialized => true;
    
    		public Task<Result> InitAsync(string connStr)
    		{
    			return Task.FromResult(Result.Ok);
    		}
    
    		public async Task<T> GetAsync<T>(string key, Func<T> defaultFunc = null, bool setDefault = false)
    		{
    			try
    			{
    				return await BlobCache.LocalMachine.GetObject<T>(key);
    			}
    			catch (Exception)
    			{
    				if (defaultFunc == null)
    					throw;
    			}
    			var value = defaultFunc();
    			if (setDefault)
    				await SetAsync(key, value);
    			return value;
    		}
    
    		public async Task<bool> SetAsync<T>(string key, T value, int expiredSeconds = 0)
    		{
    			try
    			{
    				DateTimeOffset? offset = null;
    				if (expiredSeconds > 0)
    					offset = new DateTimeOffset(DateTime.Now.AddSeconds(expiredSeconds));
    				await BlobCache.LocalMachine.InsertObject(key, value, offset);
    				return true;
    			}
    			catch
    			{
    				return false;
    			}
    		}
    
    		public async Task<bool> RemoveAsync(string key)
    		{
    			try
    			{
    				await BlobCache.LocalMachine.Invalidate(key);
    				return true;
    			}
    			catch
    			{
    				return false;
    			}
    		}
    
    		public async Task<bool> ExistsAsync(string key)
    		{
    			try
    			{
    				await BlobCache.LocalMachine.Get(key);
    				return true;
    			}
    			catch (Exception)
    			{
    				return false;
    			}
    		}
    
    		public async Task<long> SAddAsync<T>(string key, params T[] members)
    		{
    			var set = await GetAsync(key, () => new HashSet<string>(), true);
    			var c1 = set.Count;
    			set.AddRange(members.Select(t => JsonConvert.SerializeObject(t)));
    			if (await SetAsync(key, set))
    				return set.Count - c1;
    			return -1;
    		}
    
    		public async Task<long> SCountAsync(string key)
    		{
    			try
    			{
    				var col = await GetAsync<IEnumerable<object>>(key);
    				return col.Count();
    			}
    			catch (Exception)
    			{
    				return 0;
    			}
    		}
    
    		public async Task<T[]> SMembersAsync<T>(string key)
    		{
    			var set = await GetAsync(key, () => new HashSet<string>());
    			return set.Select(JsonConvert.DeserializeObject<T>).ToArray();
    		}
    
    		public async Task<bool> SIsMemberAsync<T>(string key, T member)
    		{
    			var set = await GetAsync(key, () => new HashSet<string>());
    			var mem = JsonConvert.SerializeObject(member);
    			return set.Contains(mem);
    		}
    
    		public async Task<long> SRemoveAsync<T>(string key, params T[] members)
    		{
    			var set = await GetAsync(key, () => new HashSet<string>());
    			if (set.Count == 0)
    				return 0;
    			var count = 0;
    			foreach (var member in members)
    			{
    				var mem = JsonConvert.SerializeObject(member);
    				if (set.Remove(mem))
    					count++;
    			}
    			if (await SetAsync(key, set))
    				return count;
    			return -1;
    		}
    
    		public async Task<bool> SetExpireTimeAsync(string key, int expiredSeconds)
    		{
    			if (expiredSeconds <= 0)
    				return false;
    			try
    			{
    				var data = await BlobCache.LocalMachine.Get(key);
    				DateTimeOffset? offset = null;
    				if (expiredSeconds > 0)
    					offset = new DateTimeOffset(DateTime.Now.AddSeconds(expiredSeconds));
    				await BlobCache.LocalMachine.Insert(key, data, offset);
    				return true;
    			}
    			catch (Exception e)
    			{
    				Mg.Get<IMgLog>().Error($"设置缓存过期时间失败:key={key},expiredSeconds={expiredSeconds}", e);
    				return false;
    			}
    		}
    }
    
  • 相关阅读:
    SQL语句大全
    SQL SERVER 用sql语句将一列数据拼接成一个字符串
    常用 SQl 语句大全
    巧用一条SQL语句实现其它进制到十进制转换
    sql 2005
    sql convert(varchar(10),getdate(),120)
    sqlserver 日期函数
    转:DBCC CHECKDB 数据库或表修复
    Linux下使用SFTP命令
    mySQL 教程 第7章 存储过程和函数
  • 原文地址:https://www.cnblogs.com/ghhjanes/p/11208775.html
Copyright © 2011-2022 走看看