日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
MemoryCache 使用不當導(dǎo)致的一個 BUG

 Intro

前幾天發(fā)現(xiàn)代碼里的一個 BUG,原因是 MemoryCache 使用不當,可以對于很多人來說可能都知道,但還是想分享記錄一下,避免以后寫出同樣的 BUG

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、成都小程序開發(fā)、集團企業(yè)網(wǎng)站建設(shè)等服務(wù)項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了康保免費建站歡迎大家使用!

Sample

直接來看下面的示例吧

 
 
 
 
  1. await using var services = new ServiceCollection() 
  2.     .AddMemoryCache() 
  3.     .BuildServiceProvider(); 
  4.  
  5. Console.WriteLine("----- Bad -----"); 
  6. GetValidValues(5).Dump(); 
  7. GetValidValues(8).Dump(); 
  8.  
  9. List GetValidValues(int threhold) 
  10.     var memoryCache = services.GetRequiredService(); 
  11.     var values = memoryCache.GetOrCreate("test1", entry => 
  12.     { 
  13.         return Enumerable.Range(1, 10).ToList(); 
  14.     }); 
  15.     values.RemoveAll(x => x > threhold); 
  16.     return values; 

上面的 Dump 是一個擴展方法就是把 list 內(nèi)的元素輸出出來,實現(xiàn)如下:

 
 
 
 
  1. public static void Dump(this List values) 
  2.     var value = string.Join(",", values); 
  3.     Console.WriteLine(value); 

好了,來想一下上面的輸出結(jié)果會是什么吧,期望的結(jié)果應(yīng)該是每次都輸出小于等于輸入的值,實際是什么樣的呢?實際輸出結(jié)果如下:

Fix

可以看到第二次輸出的結(jié)果和我們的期望不同,之所以會出現(xiàn)上面的問題是因為 MemoryCache 的對象是直接保存在內(nèi)存中的對象,緩存不發(fā)生變化時每次都是返回同一個對象,如果發(fā)生修改后面再獲取的就是修改后的狀態(tài)了,所以正確的做法應(yīng)該要返回一個新的對象而不是修改原來的對象,一個修改方法如下:

 
 
 
 
  1. List GetValidValues(int threhold) 
  2.     var memoryCache = services.GetRequiredService(); 
  3.     var values = memoryCache.GetOrCreate("test", entry => 
  4.     { 
  5.         return Enumerable.Range(1, 10).ToList(); 
  6.     }); 
  7.     return values.Where(v => v <= threhold).ToList(); 

修改后的輸出結(jié)果如下:

More

MemoryCache 背后實際是一個 ConcurrentDictionary,value 是一個帶著過期時間的對象 CacheEntry,

在不過期,沒有發(fā)生變化的時候每次返回都是同一個對象,作為緩存對象,應(yīng)該進行只讀操作,不應(yīng)該修改緩存的對象,如果需要修改則應(yīng)創(chuàng)建新的對象,而非使用原來的對象。

References

https://github.com/dotnet/runtime/blob/main/src/libraries/Microsoft.Extensions.Caching.Memory/src/MemoryCache.cs#L26

https://github.com/dotnet/runtime/blob/main/src/libraries/Microsoft.Extensions.Caching.Memory/src/CacheEntry.cs

https://github.com/WeihanLi/SamplesInPractice/blob/master/MemoryCacheSample/Program.cs


文章名稱:MemoryCache 使用不當導(dǎo)致的一個 BUG
文章來源:http://www.5511xx.com/article/dhijscs.html