ably ably برای هدایت شدن به سایت جدید اینجا کلیک کنید

آموزش برنامه نویسی

آموزش برنامه نویسی وب، اندروید، ویندوز , اسکیوال و...
Tell: 0912 097 5516
| Email: Hello@EduOnline.ir

Cache کردن اطلاعات ASP.NET MVC

بسم الله الرحمن الرحیم

در این بخش قصد داریم نحوه افزایش سرعت بارگذاری صفحات در ASP.NET MVC را بررسی کنیم.

افزایش سرعت صفحات در ASP.NET MVC

برای افزایش کارایی برنامه های تحت وب Cache کردن اطلاعات بسیار مهم است. کش کردن اطلاعات یک راه برای ذخیره سازی اطلاعاتی است که مجددا باید مورد دسترسی قرار می گیرند. در عمل این یک راه موثر برای افزایش کارایی وب سایت ها است.

مزایای کش کردن اطلاعات


کاهش میزبانی اطلاعات بر روی سرور

هنگامی که شما اطلاعات را بر روی کلاینت یا پروکسی کش می کنید، عملا سرور شما درخواست های کمتری را باید پاسخ دهد.

کاهش فشار بر روی پایگاه داده

وقتی شما اطلاعات را در وب سرور کش کنید، می توانید درخواست ها را از دیتابیس حذف کنید.

کاهش ترافیک شبکه

هنگامی که شما اطلاعات را بر روی کلاینت کش می کنید، ترافیک شبکه شما کاهش پیدا می کند.

حذف زمان ها برای بازیابی اطلاعات تکراری

زمان هایی که صرف استفاده از اطلاعاتی که چندین بار مورد درخواست  قرار خواهند گرفت، حذف می شود

افزایش کارایی

هنگامی که اطلاعات را کش می کنید، زمان کمتری برای بازیابی اطلاعات لازم است، ترافیک شبکه کمتر مصرف می شود، به سرور کمتر برای پاسخگویی نیاز خواهد بود و همه این کارهای باعث می شود تا کارایی سایت شما افزایش پیدا کند.

نکاتی در مورد کش کردن اطلاعات

اطلاعاتی که به صورت متناوب و مکرر مورد دسترسی قرار می گیرند را کش کنید.
از اطلاعاتی که برای هر کاربر منحصر به فرد است در کش کردن خودداری کنید.
البته ما این کار را دقیقا در ASP.NET Identity و در بحث Claims انجلم می دهیم زیرا اطلاعاتی که کش می شوند متناوب مورد نیاز هستند می خواهیم سرعت وب سایت را افزایش دهیم. این جمله کلی است و باید شما وابسته به استفاده خود از این جمله تبعیت یا عدم تبعیت کنید.

استفاده از تابع VaryByCustom برای کش کردن نسخه های متفاوت از یک صفحه بر اساس درخواست های سفارشی چون cookies, role, theme, browser

برای کش کردن با کارایی بالا از نسخه 64-bit ویندوز سرور و SQL Server استفاده کنید.

برای کش کردن اطلاعات دیتابیس مطمئن شوید به اندازه کافی Ram در اختیار دارید در غیر این صورت با کش کردن به دلیل استفاده از Ram زیاد نه تنها کارایی را افزایش نمی دهید، بلکه سرعت کار نیز کاهش پیدا می کند.
برای اطلاعاتی که مداوم در حال تغییر هستند یک زمان برای از بین رفتن کش در نظر بگیرید.

Output Cache Filter

Output Cache Filter به شما اجازه می دهد تا اطلاعاتی که درون  یک متد action به عنوان خروجی نمایش داده خواهند شده را کش کنید. به صورت پیش فرض این خاصیت بعد از مدت 60 ثانیه از بین خواهد رفت. بعد از 60 ثانیه ASP.NET MVC این اطلاعات جدید را دوباره کش می کند.

Enabling Output Caching

شما می توانید Output Caching برای یک action و یا یک controller  به صورت زیر فعال کنید:

    [OutputCache(Duration=20, VaryByParam="none")]
    public ActionResult Index()
    {
    ViewBag.Message = DateTime.Now.ToString();
    return View();
    }



خروجی Index() action برای مدت 20 ثانیه کش می شود در صورتی که شما این مقدار را تعیین نکنید به صورت پیش فرض زمان بر روی 60 ثانیه تنظیم شده است.
برای اینکه بتوانید فرایند دوباره کش شدن اطلاعات را مشاهده کنید کافی است بر روی کدها break point قرار دهید تا این فرایند مانند تصویر زیر مشاهده کنید:

آموزش asp.net MVC

آموزش asp.net MVC

آموزش asp.net MVC


OutputCache Filter Parameter

پارامتر

نوع توضیحات

CacheProfile

String

نام output cache policy به وسیله تعریف کردن تگ <outputCacheSettings> در فایل Web.config مشخص می کند.

Duration

Int

مدت زمان cache شدن اطلاعات را مخشص می کند.

Location

OutputCacheLocation

مکان cache اطلاعات را مشخص می کند که به صورت پیش فرض Any است.

NoStore

Bool

برای مشخص کردن مواردی که شما می خواهید HTTP Cache-Control را فعال و غیر فعال کنید. این فقط برای حفاظت از اطلاعات حساس است.

SqlDependency

String

برای مشخص کردن دیتابیس و جدوالی است که می خواهید Cache کنید، خیلی جالب است با تغییر اطلاعات در دیتابیس این اطلاعات Cache شده نیز بروز می شوند.

VaryByContentEncoding

String

سمیکولن را به عنوان کارکتر جدا کننده در لیست ها مشخص می کند (مانند Gzip) که خروجی Cache از روش متفاوتی برای Cache کردن استفاده می کند.

VaryByCustom

String

برای مشخص کردن custom strings است که خروجی Cache از روش متفاوتی برای Cache کردن استفاده می کند.

VaryByHeader

String

لیست های تفکیک شده با سمیکولن از نام های HTTP header که از روش متفاوتی برای Cache کردن استفاده می کند.

VaryByParam

String

لیست های تفکیک شده با سمیکولن از فرمهایی که به صورت POST یا query string ارسال می شوند و از روش متفاوتی برای Cache کردن استفاده می کند. به صورت پیش فرض Cache نمی شوند و مقدار آن none است.

آموزش SqlDependency را در چندین مطلب بررسی آموزش داده ایم برای آشنایی با این بخش به این مقاله مراجعه کنید.

Output Caching Location

به صورت پیش فرض اطلاعات در سه بخش کش می شود

  • web server
  • any proxy servers
  • user's browser

شما می توانید بخش هایی که می خواهید اطلاعات بر روی آنها کش شود را کنترل کنید. برای تغییر مکان های کش شدن اطلاعات کافی است مقدار پارامتر location را در OutputCache تنظیم کنید. این پارامتر می توانید اطلاعات زیر را دریافت کند:

  • Any
  • None
  • Client
  • Server
  • ServerAndClient
  •  Downstream


به صورت پیش فرض پارامتر location دارای مقدار Any است  که برای بسیاری از سناریو ها مناسب است اما در بعضی مواقع شما نیاز دارید برای کار خود این فرایند کش شدن اطلاعات را عوض کنید.
مثال ساده برای این مطلب می تواند فرم لاگین باشد. وقتی شما اطلاعات یک کاربر را دریافت می کنید اطلاعات او را در مرورگر کش می کنید تا همیشه بدایند او کیست، حال اکر این اطلاعات را در سرور کش کنید اطلاعات تمامی کاربرها مربوط به اخرین فردی است که لاگین کرده.
این نکته را همیشه به یاد داشته باشید، هر وقت اطلاعاتی برای تمامی کاربران یکسان و مورد نیاز است آن را بر روی سرور کش کنید.

Configure Cache Location

برای تنظیم مکان کش شدن اطلاعات باید ابتدا namespace یا همان فضای نامی System.Web.UI را به Controller خود اضافه کنید و سپس به صورت زیر می توانید مکان کش شدن اطلاعات را در Browser کاربر مشخص کنید.


    [OutputCache(Duration = 7200, Location = OutputCacheLocation.Client, VaryByParam = "none", NoStore = true)]
    public ActionResult Index()
    {
    ViewBag.Message = "Welcome : " + User.Identity.Name;
    return View();
    }

نظرات (۴)

  • امین احمدی
  • عالی بود...مرسی
    لطفا در مورد کوکی ها و همینطور ایجکس جی کوری هم مطلب بذارید
    پاسخ:
    با عرض سلام
    اگر موضوع خاصی را مد نظر دارید اطلاع دهید تا در مورد آن مطلبی ارائه شود و دوستان دیگر نیز از آن استفاده کنند.
    باتشکر
    سلام آقای شیدایی : 

    در صورتی که قصد داشته باشیم کش را مدیریت کنیم [ ()Cache.Insert ] چطور می توانیم مدت زمانی که برای کش شدن یک آیتم در نظر گرفته شده را بدست آوریم و چه مدت زمان دیگری این آیتم در کش می تواند باشدرا بدست آوریم ؟ یا از روش Attribute که خودتون مثال زدید امکان پذیر است ؟
    با تشکر از شما ...
    ممنون
    پاسخ:
    با عرض سلام خدمت شما

    می توانید با تعریف یک filter جدید که قابلیت های کش را پیاده سازی می کند، کمی در مدیریت کش دخل و تصرف داشته باشید:

    public class ActionOutputCacheAttribute : ActionFilterAttribute
    {
        // This hack is optional; I'll explain it later in the blog post
        private static MethodInfo _switchWriterMethod = typeof(HttpResponse).GetMethod("SwitchWriter", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
     
        public ActionOutputCacheAttribute(int cacheDuration)
        {
            _cacheDuration = cacheDuration;
        }
     
        private int _cacheDuration;
        private TextWriter _originalWriter;
        private string _cacheKey;
     
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            _cacheKey = ComputeCacheKey(filterContext);
            string cachedOutput = (string)filterContext.HttpContext.Cache[_cacheKey];
            if (cachedOutput != null)
                filterContext.Result = new ContentResult { Content = cachedOutput };
            else
                _originalWriter = (TextWriter)_switchWriterMethod.Invoke(HttpContext.Current.Response, new object[] { new HtmlTextWriter(new StringWriter()) });
        }
     
        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            if (_originalWriter != null) // Must complete the caching
            {
                HtmlTextWriter cacheWriter = (HtmlTextWriter)_switchWriterMethod.Invoke(HttpContext.Current.Response, new object[] { _originalWriter });
                string textWritten = ((StringWriter)cacheWriter.InnerWriter).ToString();
                filterContext.HttpContext.Response.Write(textWritten);
     
                filterContext.HttpContext.Cache.Add(_cacheKey, textWritten, null, DateTime.Now.AddSeconds(_cacheDuration), Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null);
            }
        }
     
        private string ComputeCacheKey(ActionExecutingContext filterContext)
        {
            var keyBuilder = new StringBuilder();
            foreach (var pair in filterContext.RouteData.Values)
                keyBuilder.AppendFormat("rd{0}_{1}_", pair.Key.GetHashCode(), pair.Value.GetHashCode());
            foreach (var pair in filterContext.ActionParameters)
                keyBuilder.AppendFormat("ap{0}_{1}_", pair.Key.GetHashCode(), pair.Value.GetHashCode());
            return keyBuilder.ToString();
        }
    }

    و در نهایت


    public class BlogController : Controller
    {
        [ActionOutputCache(60)] // Caches for 60 seconds
        public ActionResult LatestPosts()
        {
            ViewData["currentTime"] = DateTime.Now;
            ViewData["posts"] = new[] {
                "Here's a post",
                "Here's another post. Marvellous.",
                "Programmer escapes from custody"
            };
            return View();
        }
    }
    انشالله که توانسته باشم پاسخ شما را بدهم


    یاعلی
    سلام آقای شیدایی.. وقت بخیر.. ممنون از اینکه پاسخ دادید . 

    منظور من اینه که مثلا یک آیتم برای 180 دقیقه کش شده 
    CachDuration=180 .  برنامه را اجرا می کنیم بعد از یه مدت زمان که گذشت می خواهیم بفهمیم که این آیتم تا چند دقیقه دیگه می تونه در کش باشه .. خوب اگر از زمان شروع برنامه 20 دقیقه گذشته باشد یعنی 160 دقیقه دیگه می تونه توی کش باشه 

    چه طوری می تونیم این محاسبه را انجام بدهیم ؟ 
    ممنون از اینکه وقت میزارید و به سوالات پاسخ میدهید.. واقعا متشکرم

    پاسخ:
    با عرض سلام

    برای اینکار باید با استفاده از Ajax و java script، یک timer را طراحی کنید بنده راهکاری برای استفاده و تعیین مستقیم مدت زمان باقی مانده سراغ ندارم

    موفق باشید
    سلام آقای شیدایی

    وقت شما بخیر

    شما راهکار خاصی را برای این کار پیشنهاد می کنید ؟ 
    پاسخ:
    بابت تاخیر در پاسخ عذرخواهی می کنم، پاسخی نتوانستم برای درخوسات شما پیدا کنم.
    موفق باشید
    یاعلی
    ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
    شما میتوانید از این تگهای html استفاده کنید:
    <b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
    تجدید کد امنیتی
    up
    ما را در گوگل محبوب کنید