您的位置:首頁 > 教程 > ASP.NET > 一文掌握.Net?core中的緩存

一文掌握.Net?core中的緩存

2022-06-18 11:55:46 來源:易采站長站 作者:

一文掌握.Net?core中的緩存

目錄
1 Net Framewoke的緩存1.1 System.Web.Caching1.2 System.Runtime.Caching2 Net core的緩存介紹2.1 MemoryCache2.2 RedisCache

Cache(緩存)是優化web應用的常用方法,緩存存放在服務端的內存中,被所有用戶共享。由于Cache存放在服務器的內存中,所以用戶獲取緩存資源的速度遠比從服務器硬盤中獲取快,但是從資源占有的角度考慮緩存也不是越多越好。經常要用到且不會頻繁改變且被用戶共享的數據很適合放在緩存中。在介紹netcore的緩存前我們先回顧下net framework中的緩存技術。12C站長之家-易采站長站-Easck.Com

net framework中常用的緩存有兩種:System.Runtime.Caching和System.Web.Caching12C站長之家-易采站長站-Easck.Com

12C站長之家-易采站長站-Easck.Com

1>

12C站長之家-易采站長站-Easck.Com

1.1>

  System.Web.Caching應該是我們最熟悉的緩存類庫了,做ASP.NET開發時用到緩存基本都是使用的這個緩存組件,簡單回顧一下用法吧12C站長之家-易采站長站-Easck.Com

using System.Web;
using System.Web.Caching;
namespace FrameCache
{
    class Program
    {
        static void Main(string[] args)
        {
            //1.簡單緩存,value可以是任何類型
            HttpRuntime.Cache.Insert("mykey", "myvalue");
            Console.WriteLine($"Key為mykey的緩存:{HttpRuntime.Cache["mykey"]}");
            //2.使用緩存依賴項
            string path = Path.Combine(Environment.CurrentDirectory, @"someCacheData.xml");
            DataSet ds = new DataSet();
            ds.ReadXml(path);
            if (HttpRuntime.Cache.Get("myxml") == null)
            {
                //Dataset添加到緩存
                System.Web.HttpRuntime.Cache.Insert("myxml", ds, new CacheDependency(path));
            }
            //從緩存中獲取Dataset
            DataSet resultDs = (DataSet)HttpRuntime.Cache.Get("myxml");
            Console.WriteLine($"food下的f1節點:{resultDs.Tables["food"].Rows[0]["f1"]}");
            Console.ReadKey();
        }
    }
}

簡單的緩存就不說了,添加一下key和value就可以,緩存依賴項CacheDependency是更新緩存的重要手段,但緩存依賴項發生變化時緩存就會被清理。上邊栗子中緩存只依賴一個文件,當緩存依賴多個文件時可以這樣設置: CacheDependency cdp=new CacheDependency(new string []{"111.xml","222.xml"});。栗子中someCacheData.xml中的內容是:12C站長之家-易采站長站-Easck.Com

<?xml version="1.0" encoding="utf-8" ?>
<MyCache>
  <animals>
    <a1>cat</a1>
    <a2>dog</a2>
  </animals>
  <food>
    <f1>Apple</f1>
    <f2>pear</f2>
  </food>
</MyCache>

運行程序結果如下:12C站長之家-易采站長站-Easck.Com

12C站長之家-易采站長站-Easck.Com

12C站長之家-易采站長站-Easck.Com

1.2>

Net Framework中的MemoryCache類就是來自于這個類庫,也是開發中經常用到的類庫,net core中的緩存用法和這個類庫十分相似。簡單看一下用法吧12C站長之家-易采站長站-Easck.Com

using System.Runtime.Caching;
namespace FrameCache
{
    class Program
    {
        static void Main(string[] args)
        {
            //緩存的配置
            CacheItemPolicy policy = new CacheItemPolicy()
            {
                //緩存被刪除是的回調
                RemovedCallback = (arguments) => { Console.WriteLine($"緩存被移除的原因:{arguments.RemovedReason}"); },
                //滑動過期時間
                SlidingExpiration = TimeSpan.FromSeconds(5),
                //絕對過期時間
                //AbsoluteExpiration = DateTime.Now.AddSeconds(5),
                //優先級有兩種:Default,NotRemovable(不可移除)
                Priority = System.Runtime.Caching.CacheItemPriority.NotRemovable
            };

            //添加緩存,key為mykey,值是myvalue ,
            System.Runtime.Caching.MemoryCache.Default.Add("mykey", "myvalue", policy);
            Thread.Sleep(6000);
            Console.WriteLine(MemoryCache.Default.Get("mykey"));
            Console.ReadKey();
        }
    }
}

CacheItemPolicy 對象用于對緩存項做一個設置,如設置絕對/滑動過期時間,優先級,緩存被清理時的回調函數等。程序運行結果如下,如果我們把線程休眠的代碼注釋掉,則輸出為 “myvlaue”。12C站長之家-易采站長站-Easck.Com

12C站長之家-易采站長站-Easck.Com

12C站長之家-易采站長站-Easck.Com

2>

netcore中的緩存用戶和System.Runtime.Caching很相似,但是在功能上做了增強:緩存的key可以支持object類型(.netframework中緩存key只支持string);提供了泛型支持;可以對緩存和單個緩存項的大小做限定,可以設定緩存的壓縮比例(如緩存最大設置為100M,壓縮比例為0.2,那么緩存達到一百兆時會清除20M的緩存數據,清除時優先級低的緩存項會被優先清除);此外微軟提供了Sqlserver和Redis的緩存支持,可以讓我們更方便地實現分布式緩存。12C站長之家-易采站長站-Easck.Com

12C站長之家-易采站長站-Easck.Com

2.1>

1.過期時間  12C站長之家-易采站長站-Easck.Com

netcore中緩存相關的類庫都在Microsoft.Extensions.Caching,使用MemoryCache首先安裝包12C站長之家-易采站長站-Easck.Com

Install-Package Microsoft.Extensions.Caching.Memory

使用的方式和基本一樣,我們簡單看一下代碼12C站長之家-易采站長站-Easck.Com

using Microsoft.Extensions.Caching.Memory;
namespace CacheDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            MemoryCache memoryCache = new MemoryCache(new MemoryCacheOptions() { });
            //1.最簡單使用方式
            memoryCache.Set("mykey", "myvalue");

            //2.絕對過期時間,3秒后過期
            memoryCache.Set("key1", "value1", new DateTimeOffset(DateTime.Now.AddSeconds(3)));
            //3.絕對過期時間,效果同上
            memoryCache.Set("key2", "value2", TimeSpan.FromSeconds(3));
            //4.滑動過期時間,3秒后,即三秒鐘內被訪問,則重新刷新緩存時間為3秒后
            memoryCache.Set("key3", "value3", new MemoryCacheEntryOptions
            {
                SlidingExpiration = TimeSpan.FromSeconds(3),
            });

            Console.WriteLine("-----------暫停2秒");
            Thread.Sleep(2000);//暫停2秒
            Console.WriteLine($"key1的值:{memoryCache.Get("key1") ?? "key1被清除"}");
            Console.WriteLine($"key2的值:{memoryCache.Get("key2") ?? "key2被清除"}");
            Console.WriteLine($"key3的值:{memoryCache.Get("key3") ?? "key3被清除"}");

            Console.WriteLine("-----------暫停2秒");
            Thread.Sleep(2000);//再次暫停2秒
            Console.WriteLine($"key1的值:{memoryCache.Get("key1") ?? "key1被清除"}");
            Console.WriteLine($"key2的值:{memoryCache.Get("key2") ?? "key2被清除"}");
            Console.WriteLine($"key3的值:{memoryCache.Get("key3") ?? "key3被清除"}");
        }
    }
}

在栗子中key1,key2都是使用的絕對過期時間,key3使用的相對過期時間,2秒后第一次訪問key1、key2、key3都沒過期,其中key3的過期時間刷新了,重新設置為3秒后,所以再次暫停2秒后,key1、key2都過期了,key3仍然存在。程序運行結果如下:12C站長之家-易采站長站-Easck.Com

12C站長之家-易采站長站-Easck.Com

2.常用配置12C站長之家-易采站長站-Easck.Com

上邊我們知道了netcore中緩存的簡單用法,下邊的栗子介紹netcore中緩存的常用配置,直接看代碼12C站長之家-易采站長站-Easck.Com

class Program
    {
        static void Main(string[] args)
        {
            //緩存的配置
            MemoryCacheOptions cacheOps = new MemoryCacheOptions()
            {
                //緩存最大為100份
                //##注意netcore中的緩存是沒有單位的,緩存項和緩存的相對關系
                SizeLimit = 100,
                //緩存滿了時,壓縮20%(即刪除20份優先級低的緩存項)
                CompactionPercentage = 0.2,
                //兩秒鐘查找一次過期項
                ExpirationScanFrequency = TimeSpan.FromSeconds(3)
            };
            MemoryCache myCache = new MemoryCache(cacheOps);

            //單個緩存項的配置
            MemoryCacheEntryOptions cacheEntityOps = new MemoryCacheEntryOptions()
            {
                //絕對過期時間1
                //AbsoluteExpiration = new DateTimeOffset(DateTime.Now.AddSeconds(2)),
                //絕對過期時間2
                //AbsoluteExpirationRelativeToNow=TimeSpan.FromSeconds(3),
                //相對過期時間
                SlidingExpiration = TimeSpan.FromSeconds(3),
                //優先級,當緩存壓縮時會優先清除優先級低的緩存項
                Priority = CacheItemPriority.Low,//Low,Normal,High,NeverRemove
                //緩存大小占1份
                Size = 1
            };
            //注冊緩存項被清除時的回調,可以注冊多個回調
            cacheEntityOps.RegisterPostEvictionCallback((key, value, reason, state) =>
            {
                Console.WriteLine($"回調函數輸出【鍵:{key},值:{value},被清除的原因:{reason}】");
            });

            myCache.Set("mykey", "myvalue", cacheEntityOps);
            Console.WriteLine($"mykey的值:{myCache.Get("mykey") ?? "mykey緩存被清除了"}");
            Console.WriteLine("------------------暫停3秒");
            Thread.Sleep(3000);
            Console.WriteLine($"mykey的值:{myCache.Get("mykey") ?? "mykey緩存被清除了"}");

            Console.ReadKey();
        }
    }
}

這里需要注意netcore中設置緩存和緩存項大小是沒有單位的,緩存被清空的回調函數可以注冊多個(System.Runtime.Caching清除緩存的回調只能是一個)。程序執行結果12C站長之家-易采站長站-Easck.Com

12C站長之家-易采站長站-Easck.Com

3.IChangeToken12C站長之家-易采站長站-Easck.Com

上邊我們已經簡單了解了通過滑動過期時間和絕對過期時間來控制緩存的有效性,但是有時緩存的過期與否和時候沒有聯系,如我們緩存一個文件的內容,不管緩存多久只要文件沒有發生變化緩存都是有效的。在net framework中我們可以通過CacheDependency來控制,在net core中怎么控制呢?net core中我們可以使用IChangeToken接口輕松實現緩存的過期策略。先看一下IChangeToken接口:12C站長之家-易采站長站-Easck.Com

public interface IChangeToken
    {
        // 是否有變化發生
        bool HasChanged { get; }

        // token是否會調用回調函數,為true時才會有效 
        bool ActiveChangeCallbacks { get; }

       // 注冊一個回調函數,當有變化時觸發回調
        IDisposable RegisterChangeCallback(Action<object> callback, object state);
    }

看一下IChangeToken實現緩存過期策略的兩個例子:12C站長之家-易采站長站-Easck.Com

① 監控文件12C站長之家-易采站長站-Easck.Com

class Program
    {
        static void Main(string[] args)
        {
            string fileName = Path.Combine(Environment.CurrentDirectory, "someCacheData.xml");
            FileInfo fileInfo = new FileInfo(fileName);
            MemoryCache myCache = new MemoryCache(new MemoryCacheOptions() { });
            MemoryCacheEntryOptions cacheEntityOps = new MemoryCacheEntryOptions();
            //PollingFileChangeToken是IChangeToken的實現類,通過輪詢監控文件變化
            cacheEntityOps.AddExpirationToken(new Microsoft.Extensions.FileProviders.Physical.PollingFileChangeToken(fileInfo));
            //緩存失效時,回調函數
            cacheEntityOps.RegisterPostEvictionCallback((key, value, reason, state) => { Console.WriteLine($"文件【{key}】改動了"); });
           //添加緩存,key為文件名,value為文件內容
            myCache.Set(fileInfo.Name, File.ReadAllText(fileName), cacheEntityOps);
            Console.WriteLine(myCache.Get(fileInfo.Name));
        }
    }

PollingFileChangeToken通過輪詢來監控文件有沒有發生變化,如果文件中的內容發生改變,緩存就會自動過期。12C站長之家-易采站長站-Easck.Com

② 通過代碼控制緩存過期12C站長之家-易采站長站-Easck.Com

class Program
    {
        static void Main(string[] args)
        {
            MemoryCache memoryCache = new MemoryCache(new MemoryCacheOptions());
            MemoryCacheEntryOptions cacheEntityOps = new MemoryCacheEntryOptions();
            //使用CancellationChangeToken控制緩存過期
            CancellationTokenSource tokenSource = new CancellationTokenSource();
            cacheEntityOps.AddExpirationToken(new CancellationChangeToken(tokenSource.Token));
            //設置緩存
            memoryCache.Set("mykey", "myvalue", cacheEntityOps);
            Console.WriteLine(memoryCache.Get("mykey") ?? "緩存被清除了");
            //通過代碼清除緩存
            tokenSource.Cancel();
            Console.WriteLine(memoryCache.Get("mykey") ?? "緩存被清除了");
        }
    }

tokenSource.Cancel方法發送取消信號,這個方法會觸發緩存過期,基于此我們可以通過Cancel方法靈活的實現自定義的緩存策略。程序執行結果如下:12C站長之家-易采站長站-Easck.Com

12C站長之家-易采站長站-Easck.Com

12C站長之家-易采站長站-Easck.Com

2.2>

微軟給netcore的緩存提供了Redis和Sqlserver的實現,通過Sqlserver來緩存的場景比較少,這里我們簡單看一下官方提供的Redis緩存用法。12C站長之家-易采站長站-Easck.Com

準備工作:我已經在一臺Linu虛擬機上部署了Redis服務,虛擬機IP為192.168.70.99,Redis采用默認端口6379,密碼是xxxxx。我開發使用的電腦可以連接到虛擬機上的Redis服務器。12C站長之家-易采站長站-Easck.Com

首先添加包12C站長之家-易采站長站-Easck.Com

Install-Package Microsoft.Extensions.Caching
Install-Package Microsoft.Extensions.Caching.Redis

然后我們寫一個簡單的控制臺程序實現一下netcore中的redis緩存實現,代碼如下:12C站長之家-易采站長站-Easck.Com

static void Main(string[] args)
        {
            //獲取RedisCache實例
            RedisCache redisCache = new RedisCache(new RedisCacheOptions()
            {
                Configuration = "192.168.70.99:6379,password=xxxxx",
                InstanceName = "MyData"
            });
            //在redis中是以hash表的模式存放的
            redisCache.SetString("Name", "jack");
            redisCache.SetString("Age", "20");
            redisCache.SetString("Address", "上海", new DistributedCacheEntryOptions()
            {
                //SlidingExpiration = TimeSpan.FromSeconds(3)
                AbsoluteExpiration = DateTimeOffset.Now.AddDays(1)
            });
            //獲取緩存
            //Console.WriteLine(redisCache.GetString("Name"));
        }

執行完成,緩存數據以Hash表形式存儲在redis中,如下:12C站長之家-易采站長站-Easck.Com

12C站長之家-易采站長站-Easck.Com

這里只是介紹了netcore中redis緩存的簡單用法,其實官方提供的Redis緩存擴展中的Api很少,遠沒有MemoryCache那么多,我們使用netcore中的Redis緩存時,更多要使用Redis自身提供的功能。12C站長之家-易采站長站-Easck.Com

到此這篇關于.Net core中的緩存介紹的文章就介紹到這了,更多相關.netcore緩存介紹內容請搜索易采站長站以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持易采站長站!12C站長之家-易采站長站-Easck.Com

如有侵權,請聯系QQ:279390809 電話:15144810328

相關文章

  • [Asp.Net Core] 淺談Blazor Server Side

    [Asp.Net Core] 淺談Blazor Server Side

    在2016年, 本人就開始了一個內部項目, 其特點就是用C#構建DOM樹, 然后把DOM同步到瀏覽器中顯示. 并且在一些小工程中使用. 3年下來, 效果很不錯, 但因為是使用C#來構建控件樹, 在沒有特定
    2020-07-01
  • asp.net生成Excel并導出下載五種實現方法

    asp.net生成Excel并導出下載五種實現方法

    方法一 通過GridView(簡評:方法比較簡單,但是只適合生成格式簡單的Excel,且無法保留VBA代碼),頁面無刷新 aspx.cs部分 代碼如下: using System; using System.Collections; using System.Configuration; usi
    2019-05-16
  • Asp.Net Core用NLog記錄日志操作方法

    Asp.Net Core用NLog記錄日志操作方法

    需求 1.日志自動寫入到數據庫、寫入到文件 2.appsettings.json數據庫連接更改后,不需要去改NLog中的連接地址,啟動網站或項目時自動檢測變動然后去更改,以appsettings.json為準,保持同步
    2019-11-19
  • 使用vs2019加.net core 對WeiApi的創建過程詳解

    使用vs2019加.net core 對WeiApi的創建過程詳解

    vs2019創建webapi 1.創建新的項目 2.選擇.NET CORE的ASP .NET CORE WEB應用程序 3.定義項目名稱和存放地點 4.選擇API創建項目 5.刪除原本的無用的類 6.添加新的方法類 7.設置路由 using Microsoft.AspNe
    2020-07-03
  • 教你Asp.net下使用mysql數據庫的步驟

    教你Asp.net下使用mysql數據庫的步驟

    1. 首先需要安裝mysql, 易采站長站下載地址: //www.jb51.net/softs/2193.html 或者去mysql.com官網都可以,一路next,安裝好后,有個簡單配置,提示有個設置登錄密碼和服務名稱, 默認localhost,用
    2019-05-16
  • [Asp.Net Core]用Blazor Server Side實現圖片驗證碼

    [Asp.Net Core]用Blazor Server Side實現圖片驗證碼

    關于Blazor 由于在國內, Blazor一點都不普及, 在閱讀此文前, 建議讀者先翻看我之前寫的隨筆, 了解Blazor Server Side的特點. 在一段時間內, 我會寫一些解說分析型的 "為什么選擇 Blazor Server
    2020-07-01
  • 詳解ASP.NET Razor 語法

    詳解ASP.NET Razor 語法

    Razor 同時支持 C# (C sharp) 和 VB (Visual Basic)。 主要的 Razor C# 語法規則 Razor 代碼塊包含在 @{ ... } 中 內聯表達式(變量和函數)以 @ 開頭 代碼語句用分號結束 變量使用 var 關鍵字聲明 字符
    2020-07-07
  • .Net Core中使用ExceptionFilter過濾器的方法

    .Net Core中使用ExceptionFilter過濾器的方法

    .Net Core中有各種Filter,分別是AuthorizationFilter、ResourceFilter、ExceptionFilter、ActionFilter、ResultFilter??梢园阉麄兛醋魇?Net Core自帶的AOP的擴展封裝。 今天來看其中的一種:ExceptionFilter(用于
    2020-03-03
色七七影院_香港三级台湾三级在线播放_男人放进女人阳道猛进猛出