کشینگ در حافظه موقت در ASP.NET Core

عموما مکانیزم کشینگ این امکان را به ما میدهد که منابع کمتری را بکار ببریم. جلوگیری از لود کردن دوباره یک فایل (مثلا ذخیره یک CSS Style یا یک فایل جاوا اسکریپت در مرورگر) یا ذخیره Response یک Action با استفاده از Response Caching، یا ذخیره یک شی در حافظه موقت با استفاده از In-Memory Cache که موضوع این پست می باشد (نوع دیگری از کشینگ اصطلاحا با Distributed Caching شناخته میشود که موضوع بحث ما نیست). In-Memory Caching ساده ترین نوع کش کردن می باشد که به سادگی در ASP.NET Core قابل پیاده سازی می باشد. این نوع کشینگ معمولا زمانی استفاده می شود که نرم افزار ما بر روی یک سرور قرار دارد و اصلاحا توزیع شده نیست( در صورتی که نرم افزار ما بر روی چند سرور قرار گرفته باشد و همچنان قصد استفاده از این In-Memory Caching را داشته باشیم، Request های مختلف برای استفاده از اطلاعات موجود در کش باید به سروری هدایت شوند که کشینگ در آن اعمال می شود). با استفاده از In-Memory Caching میتوانیم انواع مختلف داده ها را بدون مشکل در حافظه نگهداری کنیم. برای مثال داده ما میتواند یک string ساده یا یک لیست از اطلاعات کارمندان باشد. یک سری قوانین در پیاده سازی و استفاده از مکانیزنم کشینگ وجود دارد که باید رعایت شود :کدهای نوشته شده برای دستیابی به اطلاعات کش همیشه باید یک راه جبران در صورت نبود اطلاعات در حافظه کش داشته باشند. مثلا هنگامی که ما یک لیستی از کالاها را در حافظه کش ذخیره کردیم و در زمان واکشی آن اطلاعات ذخیره شده وجود نداشت ( مثلا منقضی شدن مدت زمان نگهداری اطلاعات)، قطعه کد شما باید راهی برای دوباره بارگیری کردن لیست کارمندان داشته باشد.حتما در هنگام ذخیره/بازیابی اطلاعات کش، از یک کلید معتبر داخلی; مثلا نام کلاس+شناسه یا یک عبارت منحصر به فرد مربوط به داده مورد نظر استفاده کنید تا تداخلی بین داده های مختلف بوجود نیاد. بطور مثال اگر برای ذخیره نام یک دانشجو تنها از شناسه آن که مثلا 1 است استفاده کنید و برای ذخیره یک درس هم از شناسه آن درس که اتفاقا آن هم 1 می باشد استفاده کنید، در هنگام بازیابی با اطلاعات معتبری مواجه نمی شوید، چون ممکن است اطلاعات مربوط به درس با شناسه 1 بر روی اطلاعات دانشجو بازنویسی شده باشد.استفاده از یک زمان انقضای مشخص شده برای هر داده ضروری می باشد، چرا که ما از یک منبع محدود که حافظه موقت است استفاده میکنم و ممکن است در صورت لحاظ نکردن زمان انقضا مربوط به داده با درگیر کردن بخش زیادی از حافظه موقت به کمبود منبع حافظه مواجهه شویم.( در نظر داشته باشید که ASP.NET Core محدودیتی برای ذخیره داده در In-Memory Cache در نظر نمی گیرد.)بعضی از توسعه دهندگان از هاست های اشتراکی برای انتشار نرم افزار خود استفاده می کنند که در این صورت به دلیل کمبود منابع حافظه (در اختیار داشتن مقدار بسیار کمی از منبع حافظه موقت) باید دقت بیشتری در کش کردن اطلاعات لحاظ کنند و حدالامکان از کشینگ برای اطلاعات ضروری با بازه زمانی محدودتر استفاده کنند. نحوه استفاده از کشینگ حافظه موقت :در کلاس Startup و در متد ConfigureServices متد زیر را برای فعال کردن کشینگ فراخوانی میکنیم : services.AddMemoryCache ();و در قسمتی که قصد استفاده از کشینگ را داریم، عمل تزریق ImemoryCache را به Constructor انجام میدهیم، در اینجا ما در یک کنترلر به نام InfoController قصد استفاده از کشینگ را داریم : private readonly IMemoryCache _memoryCache;public InfoController (IMemoryCache memoryCache) {_memoryCache = memoryCache;}در متد/اکشن مورد نظر، بعد از تعریف یک کلید بعنوان کلید دستیابی به کش، بررسی میکنیم که در صورت خالی بودن کش، اطلاعات مورد نظر از منبع مناسب واکشی شود و در کش قرار گیرد، متغیر expirationOptions حاوی تنظمات مربوط به مدت زمان غیر فعال بودن مقدار کش شده، الویت و مدت زمان قطعی نگهداری داده کش شده است :[HttpGet]public string GetInfo () {var key = &quotinfo1&quot if (!_memoryCache.TryGetValue (key, out string info)) { info = getInformation (); var expirationOptions = new MemoryCacheEntryOptions { SlidingExpiration = TimeSpan.FromMinutes (2), Priority = CacheItemPriority.Normal, AbsoluteExpiration = DateTime.Now.AddMinutes (50)};_memoryCache.Set (key, info, expirationOptions);}return info;}نکات حائض اهمیت برای تنظیمات یک شی کش شده که در متغیر expirationOptions تعیین شده بصورت زیر است :SlidingExpiration : تعیین کننده این می باشد که یک مقدار کش شده در صورت استفاده نشدن تا چه زمانی میتواند غیر فعال شود. مثلا در مورد بالا مقدار 2 دقیقه برای این فیلد در نظر گرفته شده که یعنی اگر در مدت زمان 2 دقیقه ، این مقدار کش شده مورد استفاده قرار نگیرد، اطلاعات کش شده از بین خواهد رفت. این مقدار از مقدار زمان منقصی قطعی(فیلد پایینی) فراتر نخواهد رفتAbsoluteExpiration : زمان منقضی شدن قطعی یک مقدار کش شدهPriority : میزان اهمیت مقدار کش شده، در صورت نیاز به پاکسازی حافظه این متغییر تعیین کننده اهمیت نگهداری یه مقدار کش شده استو متد private زیر به اصطلاح یک منبع داده می باشد( در حالتهای واقعی تر این منبع می تواند یک دیتابیس یا یک سرویس خارجی باشد) :private string getInformation () {return $&quotthis is a sample text. generated at : {DateTime.Now.ToLongTimeString()}&quot}یک نمونه ساده از نحوه استفاده از In-Memory Caching در github