آموزش Caching در ASP.NET MVC

چهارشنبه 22 مهر 1394

در صورتی که برخی بخش ها مانند فروم ها، قسمت مقالات، نظرسنجی و غیره، بر روی وب سایت شما پس از مدت نسبتا زیادی بروز می شوند، می توانید بوسیله فعال سازی Cache باعث افزایش سرعت دسترسی کاربران به وب سایت خود شوید. در این مقاله می بینیم که چطور می توان cache را در برنامه کاربردی ASP.NET MVC پیاده سازی کرد.

آموزش Caching در ASP.NET MVC

پیش زمینه

به عنوان توسعه دهندگان وب در حوزه ASP.NET، اغلب درگیر توسعه صفحاتی هستیم که داینامیک هستند. برای مثال می توان محتوایی که از پایگاه داده، دایرکتوری های سرور، فایل های xml می آید، و یا مطالبی که از سایت های دیگر گرفته می شود را نام برد.

Caching به معنی ذخیره سازی چیزی در حافظه است که به دفعات مکرر استفاده می شود و این عمل باعث می شود کارایی بهتری در سایت ایجاد شود.

 کاربر بر اساس معیارهای خود محتوایی را درخواست می کند. حالا اگر پایگاه داده به دفعات مکرر، حتی بین دو درخواست یک کاربر تغییر کند، در این حالت ما تغییرات پایگاه داده را پیش بینی می کنیم، پس می توانیم داده ای که کاربر درخواست کرده را cache کنیم. اما اگر پایگاه داده مکررا تغییر نکند، می توانیم caching را در برخی قسمت های صفحه اعمال کنیم که اگر کاربر در آن قسمت درخواست پر تکرار داشت، بتواند پاسخگو باشد.

دو کلید واژه در اینجا ، فرکانس(frequency) و معیار(criteria) هستند. فرکانس تعداد دفعاتی است که ما  درخواست های کاربر برای یک صفحه مشخص را پیش بینی می کنیم و معیار، منحصر به فرد بودن نتایجی را مدیریت می کند که روی صفحه نشان داده می شود.

فرکانس بسیار مهم است زیرا ما نیاز به کشف کردن درخواست ها  در بازه زمانی مشخص داریم، زمانی که پایگاه داده در حال تغییر است ، آن را با فرکانس درخواست کاربر مقایسه می کند، بنابراین می توانیم caching را در قسمت های مجزا داشته باشیم و همچنین مطمئن شویم که کاربر داده های منسوخ شده را مشاهده نمی کند.

ضوابط و معیارها نیز مهم هستند زیرا ما باید مطمئن شویم که caching پیاده سازی شده برای صفحه روی هر معیار به صورت منحصر به فرد بوجود آمده است. این نباید موردی باشد که کاربر محتوایی را بر اساس criteria01 درخواست کند و ما مطالب cache شده نتایج criteria00 را نشان دهیم.

بنابراین با تمام این نظریه ها، اجازه دهید پیش برویم و ببینیم چگونه می توان caching را در ASP.NET MVC پیاده سازی کرد.

استفاده از کد:

انواع Caching

دو نوع Caching در ASP.NET وجود دارد:

Caching خروجی صفحه

برنامه کاربردی Caching

 

Caching خروجی صفحه

صفحه Caching خروجی به توانایی وب سرور برای cache کردن یک صفحه مشخص بعد از درخواست کاربر در حافظه خود اشاره می کند. بنابراین درخواست های بیشتر برای صفحه مشابه برای اعتبار صفحه Cache شده کنترل می شود و در منابع استفاده شده نتیجه نمی دهد( پایگاه داده و یا فایل های access) و صفحه برای کاربران از cache برگردانده می شود.

اجازه دهید یک پروژه کوچک ایجاد کنیم که نشان می دهد چگونه می توانیم page output caching را در ASP.NET MVC پیاده سازی کنیم. حالا یک view ساده را ایجاد می کنیم که زمان جاری سیستم را به کاربر نشان می دهد. کنترلر به سادگی این view را برمی گرداند.

public class TestController : Controller
{
    public ActionResult Index()
    {
        return View();
    }      
}

 

ما در View خود زمان سیستم جاری را به کاربر نشان دادیم:

@{
    ViewBag.Title = "Caching Demo";
}

Time is @DateTime.Now.ToString()

 

اگر حالا این برنامه را اجرا کنیم، زمان و تاریخ جاری سیستم را نشان می دهد. اگر این صفحه را refresh کنیم زمان نیز به روز می شود( به خاطر این که هنوز caching پیاده سازی نشده است).

 

حالا باید این صفحه را به مدت 30 ثانیه cache  کنیم برای مثال رشته زمان نباید برای 30 ثانیه تغییر کند. این عمل از طریق استفاده از صفت OutputCache در بالای یک action method ایجاد می شود. ما دو مقدار را در این صفت ارسال می کنیم، اولی زمان cache و دومی VaryByParam می باشد.

VaryByParam="none" مشخص می کند که caching به چیزی بستگی ندارد.

public class TestController : Controller
{
    [OutputCache(Duration=30, VaryByParam="none")]
    public ActionResult Index()
    {
        return View();
    }      
}

 

حالا اگر صفحه را اجرا کرده و آن را refresh کنید، زمان برای 30 ثانیه تغییر نمی کند.

 

در مثال بالا ما VaryByParam="none مشخص کرده ایم. با انجام این کار می توانیم وضعیتی را ایجاد کنیم که کاربر داده های قدیمی را ببیند. بنابراین اگر ما بخواهیم cache را بر اساس برخی انتخاب های کاربران باطل کنیم، می توانیم مقدار VaryByParam را مشخص کنیم. بنابراین اگر بخواهیم با مقادیر متفاوت cache برای درخواست های صفحه ایجاد کنیم باید query string متفاوت ایجاد کنیم. ما می توانیم مقدار varyByParam را به عنوان نامی برای query string تعیین کنیم.( یا هر نوع المان HTML که می خواهیم استفاده کنیم).

public class TestController : Controller
{
    [OutputCache(Duration = 30, VaryByParam = "none")]
    public ActionResult Index()
    {
        return View();
    }

    [OutputCache(Duration = 30, VaryByParam = "id")]
    public ActionResult Index1()
    {
        return View();
    }
}

بنابراین اگر ما برنامه را اجرا کنیم می توانیم یک نسخه cache شده برای هر مقدار "Id" در query string داشته باشیم. 

 

بنابراین  می توانیم مدتی که صفحه باید cache شود را تعیین کنیم و این به frequency که در قبل در مورد آن بحث شد بستگی دارد. مدت زمان باید انتخاب شود، بنابراین در آن زمان که ما انتظار تغییری نداریم ایجاد می شود. دیدیم که چگونه می توانیم از VaryByParam برای ایجاد اطمینان در خروجی برای هر معیار مختلف که تولید می شود استفاده کرد و نسخه Cache شده فقط برای کاربر نمایش داده نمی شود.

اگر ما صفحات خروجی مختلف بر اساس تغییر همه یا هرکدام از المان های HTML داشته باشیم، می توانیم لیستی از VaryByParam ="*" را تعیین کنیم. اجازه دهید برخی دیگر پارامترها را مشاهده کنیم که می توانیم برای سفارشی کردن رفتار caching استفاده کنیم.

VaryByParam: لیستی از رشته ها هستند که از طریق HTTP POST/GET به سرور ارسال می شوند و برای بررسی اعتبار Cache مورد استفاده قرار می گیرد.

VaryByCustom: برای نیازمندی های cache خروجی سفارشی مورد استفاده قرار می گیرد.

VaryByHeader: هدر HTTP است که اعتبار cache را تعیین می کند.

SqlDependency: یک جفت Database-tablename را تعریف می کند که به اعتبار cache بستگی دارد.

محل قرار گیری cache

در اینجا یک property مهمتر از صفت OutputCache وجود دارد که آن Location می باشد.

این property تعیین می کند که داده cache شده در کجای سرور ذخیره شود.

مقادیر ممکن برای این property به صورت زیر می باشد:

هرکدام( پیش فرض): محتوا در سه مکان cache می شود:بر روی وب سرور، هرگونه سرور پراکسی و بر روی مرورگر وب.

کلاینت: محتوا بر روی web browser(مرورگر) cache می شود.

سرور: محتوا بر روی وب سرور cache می شود.

سرور و کلاینت: محتوا بر روی وب سرور و مرورگر cache می شود.

هیچ کدام: محتوا بر روی هیچ جایی cache نمی شود.

راه دقیق تر برای تعیین صفت Cache

اگز تمام متدهای ما نیاز به یک Caching مشابه داشته باشد آنگاه به جای تعیین Cache برای تک تک متد ها می توانیم به طور ساده کنترلر را با این صفت تنظیم کنیم و Caching بر روی تمام متدهای کنترلر موثر خواهد بود.

[OutputCache(Duration = 30, VaryByParam = "none")]
public class TestController : Controller
{   
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Index1()
    {
        return View();
    }
}

 

در این مورد ما چندین متد در یک کنترلر داریم که نیاز به Caching مشابه دارند. می توانیم این مقادیر Cache را در web.config قرار دهیم و یک cacheprofile برای آن ایجاد کنیم.

<caching>
      <outputCacheSettings>
        <outputCacheProfiles>
          <add name="MyCacheProfile"
               duration="30"
               varyByParam="id"
               location="Any" />
        </outputCacheProfiles>
      </outputCacheSettings>
    </caching>

و برای استفاده از این مقادیر در این متد نیاز داریم که نام CacheProfile برای این متد تعیین کنیم.


[OutputCache(CacheProfile = "MyCacheProfile")]
public ActionResult Dummy()
{  
    return View();
}

 

Cache کردن به صورت جزئی در یک صفحه وب

در asp.net Web forms ما نیاز به ایجاد user control های سفارشی داشتیم تا بتوانیم Caching را به صورت جزیی پیاده سازی کنیم. همان را می توانیم با ایجاد partial view ساده در MVC ایجاد کنیم. Caching در این partial view توسط صفت OutputCache مربوط به متد مسئول به ارائه داده در این partial view مدیریت می شود.

برای نشان دادن این موضوع اجازه دهید یک متد دیگر به نام Index2 در کنترلر ایجاد کنیم. این متد داده ها را Cache نمی کند.

ما partial View را در View مربوط به Index2 قرار می دهیم. این partial View زمان را برای 10 ثانیه cache می کند. اجازه دهید به متدها برای این مورد نگاهی بیاندازیم.

public ActionResult Index2()
{
    return View();
}

[OutputCache(Duration = 10, VaryByParam = "none")]
public PartialViewResult PartialTest()
{
    return PartialView("SamplePartial");
}

 

View مربوط به Index2 به صورت زیر است:

@{
    ViewBag.Title = "Caching Demo";
}

Time is @DateTime.Now.ToString()

<br /><br />
Partial page here: @Html.Action("PartialTest")

 

و در آخر کد Partial View به صورت زیر است:


Time: @DateTime.Now.ToString()

حالا اگر ما برنامه را اجرا کنیم و آن را به متدIndex2 هدایت کنیم می توانیم ببینیم که زمان از صفحه اصلی  Cache نمی شود اما زمان آمده از Partial Viee برای 10 ثانیه Cache می شود.

 

برنامه کاربردی Caching

Caching داده های برنامه، یک مکانیسم برای ذخیره Data object روی cache می باشد. این هیچ ربطی با caching صفحه ندارد. ASP.NET به ما اجازه می دهد تا شی را در یک Key-Value بر اساس cache ذخیره کند. ما می توانیم از این برای ذخیره داده ایی که باید cache  شود استفاه شود.

اجازه دهید تا بر روی یک مثال ساده کار کنیم و سعی کنیم تا رشته DateTime را در برنامه Cache ذخیره کنیم.

public ActionResult Index3()
{
    if (System.Web.HttpContext.Current.Cache["time"] == null)
    {
        System.Web.HttpContext.Current.Cache["time"] = DateTime.Now;
    }

    ViewBag.Time = ((DateTime)System.Web.HttpContext.Current.Cache["time"]).ToString();
    return View();
}

 

View مربوط به این Action به صورت زیر است:

@{
    ViewBag.Title = "Caching Demo";
}

Time is @ViewBag.Time

 

حالا اگر برنامه را اجرا کنیم و آن را به متد Index3 هدایت کنیم زمان را خواهیم دید. اما مشکلی برای وجود چند زمان نمی باشد. ما این صفحه را refresh می کنیم، مقدار زمان تغییر نمی کند. زیرا که این مقدار از cache برنامه می آید.

همچنین ما در همه جا cache را بی اعتبار نمی کنیم. پارامترهای متفاوت مرتبط با داده برنامه وجود دارد که میتواند برای باطل کردن مقادیر کنترل استفاده شود.

 

پارامترهای متفاوت مرتبط با داده برنامه وجود دارد که می تواند برای باطل کردن مقادیر کنترل استفاده شود.

وابستگی ها(Dependency): هر فایل یا آیتم در Cache که این بخش cache را باطل می سازد.

absoluteExpiration: زمان مطلق زمانی است که این شی باید از cache پاک شود.

slidingExpiration: زمان نسبی زمانی است که  این شی باید از cache پاک شود.

اولویت(priority): اولویت یک بخش را تعیین می کند.این برای اجرای سرور مناسب است که پاک کردن بخش ها یک به یک از cache با کمترین اولویت انجام می گیرد.

onRemoveCallBack: این یک اداره کننده رخداد است که زمانی که شی از cache پاک کی شود فراخوانی می شود. این به ما مکانی برای action های بیشتر می دهد.

در این مقاله، مشاهده کردیم که چطور می توانیم caching را در یک  پروژه ASP.NET پیاده سازی کنیم. این مقاله برای افراد تازه کار در MVC ارائه شده است .

 

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید