一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - ASP.NET教程 - ASP.NET Core - 緩存之內(nèi)存緩存(上)

ASP.NET Core - 緩存之內(nèi)存緩存(上)

2023-05-08 00:03未知服務(wù)器之家 ASP.NET教程

1. 緩存 緩存指的是在軟件應(yīng)用運(yùn)行過程中,將一些數(shù)據(jù)生成副本直接進(jìn)行存取,而不是從原始源(數(shù)據(jù)庫(kù),業(yè)務(wù)邏輯計(jì)算等)讀取數(shù)據(jù),減少生成內(nèi)容所需的工作,從而顯著提高應(yīng)用的性能和可伸縮性,使用好緩存技術(shù),有利于提

1. 緩存

緩存指的是在軟件應(yīng)用運(yùn)行過程中,將一些數(shù)據(jù)生成副本直接進(jìn)行存取,而不是從原始源(數(shù)據(jù)庫(kù),業(yè)務(wù)邏輯計(jì)算等)讀取數(shù)據(jù),減少生成內(nèi)容所需的工作,從而顯著提高應(yīng)用的性能和可伸縮性,使用好緩存技術(shù),有利于提高我們提升用戶體驗(yàn)性。

對(duì)于緩存的使用有以下一些注意點(diǎn):

  • 緩存最適用于不常更改且生成成本很高的數(shù)據(jù)。
  • 代碼應(yīng)始終具有回退選項(xiàng),以提取數(shù)據(jù),而不依賴于可用的緩存值。
    我們應(yīng)該以從不依賴于緩存數(shù)據(jù)的方式編寫和測(cè)試應(yīng)用。緩存是會(huì)失效的,我們?cè)谶M(jìn)行應(yīng)用開發(fā)時(shí)應(yīng)該考慮到緩存失效的情況,提供緩存失效時(shí)按照正常邏輯獲取相關(guān)數(shù)據(jù)的方式。
  • 緩存使用短缺資源:內(nèi)存。 我們應(yīng)該限制緩存增長(zhǎng):
    • 不要將外部輸入插入到緩存中。 例如,不建議使用用戶提供的任意輸入作為緩存鍵,因?yàn)檩斎肟赡軙?huì)消耗不可預(yù)測(cè)的內(nèi)存量。
    • 使用過期限制緩存增長(zhǎng)。
    • 應(yīng)當(dāng)限制緩存的大小,避免緩存過度增長(zhǎng)

軟件開發(fā)中對(duì)緩存的使用一般有兩種情況,一種是內(nèi)存緩存,一種是分布式緩存。

2. NET Core 的內(nèi)存緩存

內(nèi)存緩存是最簡(jiǎn)單的一種緩存方式,就是使用應(yīng)用所在的服務(wù)器的內(nèi)存來保存一些數(shù)據(jù)副本,利用內(nèi)存讀寫比磁盤、網(wǎng)絡(luò)請(qǐng)求快的特點(diǎn)來提供應(yīng)用性能。內(nèi)存緩存一般應(yīng)用于單機(jī)應(yīng)用,一旦應(yīng)用重啟,內(nèi)存緩存中的數(shù)據(jù)就會(huì)丟失。

如果是在服務(wù)器場(chǎng)(多個(gè)服務(wù)器)中運(yùn)行的應(yīng)用使用內(nèi)存緩存,應(yīng)確保在使用內(nèi)存中緩存時(shí)會(huì)話是粘滯的。 粘滯會(huì)話可確保來自客戶端的請(qǐng)求都轉(zhuǎn)到同一服務(wù)器。

2. 1 內(nèi)存緩存啟用

.NET Core 框架下對(duì)于內(nèi)存緩存的使用是通過 IMemoryCache ,可以通過將其注冊(cè)到容器中,之后在需要的地方注入使用。對(duì)于大多數(shù)應(yīng)用,在 Program.cs 中調(diào)用許多其他 Add{Service} 方法可以啟用 IMemoryCache,例如 AddMvc、AddControllersWithViews、AddRazorPages、AddMvcCore().AddRazorViewEngine 等 。

如果應(yīng)用中沒有使用到上述的這些方法,我們也可以自行引入 Microsoft.Extensions.Caching.Memory Nuget 包,通過 AddMemoryCache 方法啟動(dòng)內(nèi)存緩存。為了方便演示,以下示例使用 .NET 6 控制臺(tái)應(yīng)用。

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

Host.CreateDefaultBuilder(args)
	.ConfigureServices(services =>
	{
		services.AddMemoryCache();
	})
	.Build().Run();

2. 2 內(nèi)存緩存基本用法

內(nèi)存緩存的使用,只需要將 IMemoryCache 服務(wù)注入到類中進(jìn)行使用即可。我們可以通過 TryGetValue 方法嘗試從緩存中獲取數(shù)據(jù),通過 Set 方法向緩存中添加數(shù)據(jù)。

public interface ICacheService
{
	public void PrintDateTimeNow();
}

public class CacheService : ICacheService
{
	public const string CacheKey = "CacheTime";
	private readonly IMemoryCache _cache;
	public CacheService(IMemoryCache memoryCache)
	{
		_cache = memoryCache;
	}

	public void PrintDateTimeNow()
	{
		var time = DateTime.Now;
		if(!_cache.TryGetValue(CacheKey, out DateTime cacheValue))
		{
			cacheValue = time;
			_cache.Set(CacheKey, cacheValue);
		}
		time = cacheValue;

		Console.WriteLine("緩存時(shí)間:" + time.ToString("yyyy-MM-dd HH:mm:ss"));
		Console.WriteLine("當(dāng)前時(shí)間:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
	}
}

using CacheSample;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = Host.CreateDefaultBuilder(args)
	.ConfigureServices(services =>
	{
		services.AddMemoryCache();
		services.AddTransient<ICacheService, CacheService>();
	})
	.Build();

var service = host.Services.GetRequiredService<ICacheService>();
service.PrintDateTimeNow();

Task.Delay(TimeSpan.FromSeconds(2)).Wait();

service.PrintDateTimeNow();

host.Run();

通過控制臺(tái)打印結(jié)果,可以看到,當(dāng)前時(shí)間已經(jīng)改變,但是緩存的時(shí)間是之前的數(shù)據(jù)。

ASP.NET Core - 緩存之內(nèi)存緩存(上)

緩存系統(tǒng)將緩存項(xiàng)存儲(chǔ)為鍵值對(duì),內(nèi)存緩存中鍵和值都可以是任意類型,不過一般情況下我們會(huì)將字符串作為鍵。之后會(huì)講到的分布式緩存中,則要求值必須是 byte[] 類型。

除此之外,還可以通過 GetOrCreate 或 GetOrCreateAsync 將獲取和添加的操作結(jié)合。

public class CacheService : ICacheService
{
	public const string CacheKey = "CacheTime";
	private readonly IMemoryCache _cache;
	public CacheService(IMemoryCache memoryCache)
	{
		_cache = memoryCache;
	}

	public void PrintDateTimeNow()
	{
		//var time = DateTime.Now;
		//if(!_cache.TryGetValue(CacheKey, out DateTime cacheValue))
		//{
		//    cacheValue = time;
		//    _cache.Set(CacheKey, cacheValue);
		//}
		//time = cacheValue;

		var time = _cache.GetOrCreate(CacheKey, cacheEntry =>
		{
			return DateTime.Now;
		});

		Console.WriteLine("緩存時(shí)間:" + time.ToString("yyyy-MM-dd HH:mm:ss"));
		Console.WriteLine("當(dāng)前時(shí)間:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
	}
}

ASP.NET Core - 緩存之內(nèi)存緩存(上)

除了 TryGetValue 方法外,如果你確定緩存中一定存在相應(yīng)的數(shù)據(jù),還可以通過 Get 方法獲取數(shù)據(jù),Get 方法支持泛型,可以直接進(jìn)行類型轉(zhuǎn)換,但是如果緩存中不存在該緩存項(xiàng),則會(huì)返回對(duì)應(yīng)類型的默認(rèn)值。

var timeCache = _cache.Get<DateTime>(CacheKey);![image]

2.3 緩存過期設(shè)置

一般情況下,我們會(huì)對(duì)緩存數(shù)據(jù)設(shè)置過期時(shí)間,一個(gè)是為將一些長(zhǎng)期未被訪問的緩存條目移除,避免緩存過度增長(zhǎng),一方面是為了更新數(shù)據(jù),避免長(zhǎng)時(shí)間的數(shù)據(jù)副本和源數(shù)據(jù)不一致。

.NET Core 下內(nèi)存緩存的過期時(shí)間設(shè)置可以通過以下的方式:

(1) 通過 Set 方法設(shè)置

var time = DateTime.Now;
if (!_cache.TryGetValue(CacheKey, out DateTime cacheValue))
{
	cacheValue = time;
	// 設(shè)置絕對(duì)過期時(shí)間
	// 兩種實(shí)現(xiàn)的功能是一樣的,只是時(shí)間設(shè)置的方式不同而已
	// 傳入的是 AbsoluteExpirationRelativeToNow, 相對(duì)當(dāng)前的絕對(duì)過期時(shí)間,傳入時(shí)間差,會(huì)根據(jù)當(dāng)前時(shí)間算出絕對(duì)過期時(shí)間
	_cache.Set(CacheKey, cacheValue, TimeSpan.FromSeconds(2));
	// 傳入的是 AbsoluteExpiration,絕對(duì)過期時(shí)間,傳入一個(gè)DateTimeOffset對(duì)象,需要明確的指定具體的時(shí)間
	// _cache.Set(CacheKey, cacheValue, DateTimeOffset.Now.AddSeconds(2));
}
time = cacheValue;

調(diào)整一下入口文件的代碼,如下:

var service = host.Services.GetRequiredService<ICacheService>();
service.PrintDateTimeNow();

Task.Delay(TimeSpan.FromSeconds(1)).Wait();
service.PrintDateTimeNow();

Task.Delay(TimeSpan.FromSeconds(2)).Wait();
service.PrintDateTimeNow();

可以看到,在第二次輸出的時(shí)候,緩存沒過期,時(shí)間是不變的,第三次的時(shí)候緩存過期了,時(shí)間改變了。

ASP.NET Core - 緩存之內(nèi)存緩存(上)

對(duì)于緩存過期時(shí)間的設(shè)置,除了絕對(duì)過期時(shí)間,還有緩動(dòng)過期時(shí)間。滑動(dòng)過期時(shí)間是指,如果在規(guī)定的過期時(shí)間內(nèi)緩存有被再一次調(diào)用,過期時(shí)間就會(huì)重新更新,從頭開始計(jì)算,每次被調(diào)用都會(huì)重新開始。

Set 方法沒有直接的參數(shù)設(shè)置滑動(dòng)過期時(shí)間,只能通過 MemoryCacheEntryOptions 對(duì)象設(shè)置,當(dāng)然相對(duì)過期時(shí)間等其他配置也可以通過該對(duì)象設(shè)置。

var memoryCacheEntryOption = new MemoryCacheEntryOptions();
// 滑動(dòng)過期時(shí)間是一個(gè)相對(duì)時(shí)間
memoryCacheEntryOption.SlidingExpiration = TimeSpan.FromSeconds(3);
_cache.Set(CacheKey, cacheValue, memoryCacheEntryOption);

ASP.NET Core - 緩存之內(nèi)存緩存(上)

可以看到,緩存時(shí)間一直沒有變,因?yàn)殡m然三次輸出時(shí)間加起來超過了三秒,但是三次輸出之間的間隔都沒有超過3秒,而每調(diào)用一次緩存都會(huì)刷新超時(shí)時(shí)間,所以緩存一直沒有過期。

(2) 通過 CreateEntry 方法設(shè)置

var time = DateTime.Now;
if (!_cache.TryGetValue(CacheKey, out DateTime cacheValue))
{
	cacheValue = time;
	var entry = _cache.CreateEntry(CacheKey);
	// 設(shè)置絕對(duì)過期時(shí)間
	// 兩種實(shí)現(xiàn)的功能是一樣的,只是時(shí)間設(shè)置的方式不同而已
	// 傳入的是 AbsoluteExpirationRelativeToNow, 相對(duì)當(dāng)前的絕對(duì)過期時(shí)間,傳入時(shí)間差,會(huì)根據(jù)當(dāng)前時(shí)間算出絕對(duì)過期時(shí)間
	entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(2);
	// 傳入的是 AbsoluteExpiration,絕對(duì)過期時(shí)間,傳入一個(gè)DateTimeOffset對(duì)象,需要明確的指定具體的時(shí)間
	entry.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(2);
	entry.Value = cacheValue;
}
time = cacheValue;

(3) 通過 GetOrCreate 或 GetOrCreateAsync 方法設(shè)置

var time = _cache.GetOrCreate(CacheKey, cacheEntry =>
{
	// 兩種實(shí)現(xiàn)的功能是一樣的,只是時(shí)間設(shè)置的方式不同而已
	// 相對(duì)當(dāng)前的絕對(duì)過期時(shí)間,傳入時(shí)間差,會(huì)根據(jù)當(dāng)前時(shí)間算出絕對(duì)過期時(shí)間
	cacheEntry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(3);
	// 絕對(duì)過期時(shí)間,傳入一個(gè)DateTimeOffset對(duì)象,需要明確的指定具體的時(shí)間
	// cacheEntry.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(2);
	// 滑動(dòng)過期時(shí)間是一個(gè)相對(duì)時(shí)間
	cacheEntry.SlidingExpiration = TimeSpan.FromSeconds(3);
	return DateTime.Now;
});

GetOrCreate 或 GetOrCreateAsync 方法的回調(diào)參數(shù)其實(shí)就是實(shí)現(xiàn)了 ICacheEntry 接口的對(duì)象。

這里同時(shí)設(shè)置了絕對(duì)過期時(shí)間和滑動(dòng)過期時(shí)間,對(duì)于一個(gè)緩存項(xiàng),僅具有滑動(dòng)過期時(shí)間的緩存項(xiàng)集有永不過期的風(fēng)險(xiǎn)。 如果在滑動(dòng)過期間隔內(nèi)重復(fù)訪問緩存項(xiàng),則該項(xiàng)永遠(yuǎn)不會(huì)過期。 將滑動(dòng)過期與絕對(duì)過期相結(jié)合,以確保項(xiàng)目過期。 絕對(duì)過期時(shí)間設(shè)置一個(gè)上限,即在滑動(dòng)過期間隔內(nèi)未請(qǐng)求該項(xiàng)時(shí),仍允許該項(xiàng)提前過期的時(shí)間。 如果經(jīng)過了可調(diào)到期間隔或絕對(duì)到期時(shí)間,則會(huì)從緩存中逐出項(xiàng)。

可以看到輸出結(jié)果如下:

ASP.NET Core - 緩存之內(nèi)存緩存(上)

第三次調(diào)用的時(shí)候,時(shí)間改變了,這是因?yàn)檩斎牖瑒?dòng)過期時(shí)間一直在更新,但是絕對(duì)過期時(shí)間超過了,所以緩存失效了。

這一篇就先到這里,后面還有內(nèi)容,但是考慮到如果全塞在一篇里面的話,這篇文章就太長(zhǎng)了,大家的閱讀體驗(yàn)會(huì)不大好,所以就拆成兩篇了。



參考文章:
ASP.NET Core 中的內(nèi)存中緩存



ASP.NET Core 系列:

目錄:ASP.NET Core 系列總結(jié)
上一篇:ASP.NET Core - 選項(xiàng)系統(tǒng)之源碼介紹

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 色777777女人色 | www.日本视频 | 欧美视频黑鬼大战白妞 | 传说之下羊妈挤羊奶网站 | 国产性视频 | 亚洲成综合人影院在院播放 | 成人18网址在线观看 | 日本高清免费中文字幕不卡 | www.最色| 国内自拍网红在线综合 | 美女草b| 波多野结衣在线观看中文字幕 | 日本一区二区高清免费不卡 | 99在线观看国产 | 国产动作大片 | 网友偷自拍原创区 | 男人猛激烈吃奶gif动态图 | 欧美日韩精品一区二区三区高清视频 | 日韩人成 | 2022色婷婷综合久久久 | beeg日本高清xxxx18 | 我被黑人彻底征服的全文 | 午夜影院费试看黄 | www视频在线免费观看 | 视频一区在线观看 | 92福利网| 久久囯产精品777蜜桃传媒 | 1313午夜精品理伦片 | 三级aa久久 | 超91精品手机国产在线 | 欧美艳星kagneyiynn高清 | 波多野结衣52部合集在线观看 | 亚洲AV久久无码精品九九软件 | 亚洲成人免费观看 | 亚洲女bbwxxxx另类 | 国产精品福利在线观看秒播 | 日本网 | 4s4s4s4s色大众影视 | 国产精品视频久久久 | 东方影库四虎 | 日本美女动态图片 |