جستجو در محصولات

گالری پروژه های افتر افکت
گالری پروژه های PSD
جستجو در محصولات


تبلیغ بانک ها در صفحات
ربات ساز تلگرام در صفحات
ایمن نیوز در صفحات
.. سیستم ارسال پیامک ..
افزايش كارآئي برنامه هاي وب در ASP.NET 2.0 ( بخش اول )
-(3 Body) 
افزايش كارآئي برنامه هاي وب در ASP.NET 2.0 ( بخش اول )
Visitor 416
Category: دنياي فن آوري
يكي از ملزومات كليدي در هر نوع برنامه كامپيوتري ميزان كارائي و قابليت پاسخگوئي سريع آن به كاربران است . طراحان و پياده كنندگان برنامه هاي كامپيوتري مي بايست در زمان طراحي ، پياده سازي و نوشتن كد به اين موضوع توجه جدي داشته باشند.
برنامه هاي وب با توجه به ماهيت و رسالت خود مي بايست قادر به ارائه خدمات مورد نياز به صدها و يا هزاران متقاضي همزمان به سادگي و با سرعت مطلوب باشند. به عبارت ديگر ، همزمان با افزايش كاربران نمي بايست شاهد افت سرعت و كارآئي يك برنامه وب باشيم .
با ارائه فريمورك دات نت و به دنبال آن ASP.NET ، پياده سازي يك برنامه وب بطرز ناباورانه اي ساده شده است . همين موضوع باعث شده است كه طراحان و پياده كنندگان بيشتر در انديشه طراحي و پياده سازي سريع برنامه هاي وب باشند و به مسائل مربوط به كارآئي برنامه كمتر توجه نمايند .
پياده كنندگان برنامه هاي وب با استفاده از فناوري ASP.NET مي بايست با بكارگيري مجموعه اي از ترفندها ، فناوري ها و رعايت برخي نكات كليدي اقدام به پياده سازي برنامه هاي وب با كارآئي بالا نمايند .
در اين مقاله و ساير مقالاتي كه در آينده منتشر خواهد شد قصد داريم به برخي از روش هاي موجود به منظور طراحي و پياده سازي يك برنامه وب كارآ اشاره نمائيم . بدين منظور بر روي سه محور اساسي زير متمركز خواهيم شد :
• طراحي براي كارآئي : در اين رابطه به مجموعه اي از نكات كليدي اشاره خواهيم كرد كه رعايت آنها در زمان طراحي مي تواند زمينه پياده سازي يك برنامه وب كارآ را فراهم نمايد .
• تست برنامه قبل از عملياتي شدن آن : يكي از مسائل مهم در ارتباط با برنامه هاي وب ، عدم تست آنها با شرايط مشابه و يا نزديك به محيط واقعي است . در اين راستا مي توان از نرم افزارها و يا ابزارهاي مختلفي استفاده كرد تا بتوان عملكرد و سرويس دهي يك برنامه وب را قبل از زير بار رفتن واقعي مشاهده و بررسي نمود . شركت مايكروسافت در اين رابطه ابزارها و برنامه هاي متعددي را ارائه نموده است كه به بررسي آنها خواهيم پرداخت .
• پياده سازي سيستم caching : با پياده سازي سيستم caching در سطوح متفاوت و caching داده مي توان كارآئي برنامه هاي وب را بطرز كاملا" محسوسي افزايش داد. در اين بخش به نحوه پياده سازي سيستم caching در برنامه هاي وب اشاره خواهيم كرد .
در ادامه بر روي اولين محور متمركز و به بررسي مسائل مرتبط با آن خواهيم پرداخت .

طراحي براي كارآئي

توجه و رعايت موارد زير پياده كنندگان را در جهت پياده سازي برنامه هاي وب با كارآئي بالا كمك خواهد كرد :

مكانيزم ترجمه كد در ASP.NET

برنامه هاي نوشته شده با استفاده از ASP.NET داراي كارآئي بمراتب بيشتري نسبت به برنامه هاي نوشته شده با استفاده از ASP كلاسيك مي باشند . اين دستاورد ناشي از ترجمه اتوماتيك كد در ASP.NET است . در صفحات قديمي نوشته شده با استفاده از ASP كلاسيك ، كدها و يا اسكريپت هاي موجود در يك صفحه براي هر يك از درخواست هاي كاربران پردازش مي گرديد . در ASP.NET ، هر كلاس صفحه در اولين مرتبه دستيابي كمپايل و براي درخواست هاي آتي cache مي گردد .
زماني كه اولين مرتبه يك كاربر صفحه اي را درخواست مي نمايد ( و يا اولين مرتبه دستيابي پس از ايجاد تغييرات در صفحه ) ، يك تاخير قابل ملاحظه در زمان پاسخ به درخواست خود را مشاهده مي نمايد ( تاخير ناشي از ترجمه صفحه ) . براي برخورد با اين موضوع مي توان از روش precompilation استفاده نمود . با استفاده از روش فوق پس از استقرار صفحات بر روي سرويس دهنده وب ، بلافاصله امكان درخواست و بازيابي سريع آنها براي متقاضيان فراهم مي گردد .

كنترل هاي سرويس دهنده

كنترل هاي سرويس دهنده عناصر اصلي در يك صفحه ASP.NET مي باشند و load زيادي را به برنامه تحميل نخواهند كرد . اين نوع كنترل ها معمولا" داراي كارآئي بمراتب بهتري نسبت به زماني مي باشند كه يك صفحه به صورت پويا و با استفاده از ترفندهائي نظير متد Response. Write خروجي خود را توليد مي نمايد.
در برخي موارد ضرورتي به استفاده از كنترل هاي سرويس دهنده ASP.NET در يك صفحه وب نخواهيم داشت . به عنوان نمونه ،‌ در صورتي كه داراي يك متن ايستا مي باشيم كه هرگز ضرورتي به دستيابي و تغيير آن در زمان اجراء و از طريق كد نداريم ، لزومي به استفاده از كنترلي نظير label نخواهيم داشت . در چنين مواردي مي توان به سادگي متن مورد نظر را با استفاده از امكانات HTML در فايل aspx. قرار داد . در ويژوال استوديو مي توان از كنترل DIV ( موجود در بخش HTML ، منوي Toolbox) استفاده كرد. در واقع ما تكليف متن مورد نظر جهت نمايش در يك صفحه aspx . را نه در زمان اجراء بلكه در زمان طراحي مشخص كرده ايم .
يكي ديگر از نكات مهم در زمان استفاده از كنترل هاي سرويس دهنده در صفحات وب ، توجه به رفتار آنها در ارتباط با نگهداري داده پس از ارسال مجدد به سرويس دهنده مي باشد . به صورت پيش فرض ، مقادير مرتبط با كنترل هاي سرويس دهنده نظير مقدار درج شده در يك TextBox ، پس از postback بطور اتوماتيك در view state ذخيره مي گردد . در واقع ، view state مكانيزمي براي نگهداري داده كنترل هاي سرويس دهنده است كه هدف آن غلبه بر محدوديت پروتكل HTTP است ( ماهيت stateless ) .
view state ، يك نام مناسب براي ذخيره داده در يك فيلد ورودي مخفي درون صفحه است . پس از post back ( ارسال مجدد براي‌ سرويس گيرنده ) يك صفحه ، سرويس دهنده قادر به بررسي مقادير نگهداري شده در view state و استفاده از آنها با توجه به شرايط حاكم بر برنامه مي باشد . view state يك قابليت عالي است چراكه اجازه نگهداري وضعيت را با استفاده از امكانات سرويس گيرنده فراهم مي نمايد و در اين رابطه از كوكي و حافظه سرويس دهنده براي ذخيره وضعيت استفاده نمي گردد .
تعداد زيادي از كنترل هاي سرويس دهنده ASP.NET از view state براي نگهداري تنظميات خود در زمان تعامل با عناصر موجود بر روي صفحه استفاده مي نمايند ( مثلا" ذخيره صفحه جاري در زمان استفاده از ويژگي paging در كنترل سرويس دهنده gridview ) .
در زمان استفاده از view state توجه به موارد زير ضروري است :
• playload صفحه را در زمان درخواست و ارائه افزايش مي دهد .
• افزايش overhead در زمان serializing و deserializing داده ذخيره شده در view state كه براي سرويس دهنده post-back شده است .
• افزايش تخصيص حافظه بر روي سرويس دهنده
كنترل هاي سرويس دهنده علاقه زيادي به استفاده از view state دارند حتي در مواردي كه به وجود آن نياز نمي باشد . به صورت پيش فرض viewstate فعال است و در صورت عدم نياز مي بايست آن را در سطح صفحه و يا كنترل غيرفعال نمود . در رابطه با يك كنترل كافي است كه خصلت EnableViewState را false و يا مي توان آن را به صورت سراسري و در سطح page غير فعال نمود . دستور زير نحوه انجام اين كار را نشان مي دهد :

<%@ Page EnableViewState="false" %> 

براي غير فعال كردن view state در سطح صفحه و يا كنترل از قوانين زير مي توان استفاده نمود :
• در صورتي كه در صفحه اي post back انجام نمي گيرد و يا صفحه مي بايست همواره براي هر يك از كنترل هاي موجود بر روي صفحه و به ازاء هر درخواست مجددا" توليد گردد ، مي بايست view state را در سطح page غير فعال نمود .
• در صورتي كه ضرورتي به نگهداري داده مرتبط با يك كنترل سرويس دهنده در view state نمي باشد مي بايست آن را براي كنترل مورد نظر غير فعال نمود . بدين منظور لازم است كه مقدار EnableViewState مربوط به كنترل معادل False در نظر گرفته شود .
• در صورتي كه كنترل در زمان طراحي مقداردهي شده است و در زمان اجراء مقدار آن تغيير نمي يابد ، خصلت EnableViewState آن مي بايست false در نظر گرفته شود .
• در صورتي كه كنترل با هر post back ، مجددا" خوانده شده و refresh مي گردد و ضرورتي به نگهداري مقدار داده قبلي وجود نداشته باشد ، خصلت EnableViewState آن مي بايست false در نظر گرفته شود .
• در صورتي كه لازم است انتخاب كاربر پس از postback صفحه بازيابي گردد ، مي بايست view state را براي كنترل مورد نظر فعال كرد.
view state ، عموما" كند شدن سرويس دهنده را به دنبال نخواهد داشت بلكه حجم صفحه را افزايش داده و مدت زمان ارسال صفحه براي سرويس گيرنده را زياد خواهد كرد . در چنين مواردي كاربران اين برداشت را خواهند داشت كه برنامه كند و قادر به ارائه پاسخ سريع به آنان نمي باشد ، خصوصا" در مواردي كه ارتباط بين سرويس گيرنده و سرويس دهنده از طريق يك خط با سرعت پائين برقرار شده باشد .
عدم استفاده صحيح از view state در برخي موارد مي تواند ادامه حيات موثر يك برنامه وب را با چالش جدي مواجه نمايد . اين موضوع در برنامه هائي كه از كنترل هاي زيادي در يك صفحه استفاده و حجم بالائي از داده را در خود نگهداري مي نمايند، مضاعف مي گردد. در چنين مواردي داده دو مرتبه به صفحه وب اضافه مي گرد : مستقيما" در كد HTML مرتبط با كنترل و مجددا" در يك فيلد مخفي براي view state . داده فوق با هر post back بين سرويس گيرنده و سرويس دهنده مبادله مي گردد .
با استفاده از page tracing مي توان از تعداد بايتي كه view state مصرف مي كند آگاهي يافت .
بحث خود را با معرفي سه محور اساسي زير آغاز و با تمركز بر روي اولين محور ادامه داديم .
• طراحي براي كارآئي : در اين رابطه به مجموعه اي از نكات كليدي اشاره خواهيم كرد كه رعايت آنها در زمان طراحي مي تواند زمينه پياده سازي يك برنامه وب كارآ را فراهم نمايد .
• تست برنامه قبل از عملياتي شدن آن : يكي از مسائل مهم در ارتباط با برنامه هاي وب ، عدم تست آنها با شرايط مشابه و يا نزديك به محيط واقعي است . در اين راستا مي توان از نرم افزارها و يا ابزارهاي مختلفي استفاده كرد تا بتوان عملكرد و سرويس دهي يك برنامه وب را قبل از زير بار رفتن واقعي مشاهده و بررسي نمود . شركت مايكروسافت در اين رابطه ابزارها و برنامه هاي متعددي را ارائه نموده است كه به بررسي آنها خواهيم پرداخت .
• پياده سازي سيستم caching : با پياده سازي سيستم caching در سطوح متفاوت و caching داده مي توان كارآئي برنامه هاي وب را بطرز كاملا" محسوسي افزايش داد. در اين بخش به نحوه پياده سازي سيستم caching در برنامه هاي وب اشاره خواهيم كرد .
در اين بخش همچنان بر روي اولين محور متمركز و به بررسي مسائل در ارتباط با بانك هاي اطلاعاتي و تاثير آنها در كارآئي يك برنامه وب اشاره خواهيم كرد .

دستيابي به بانك اطلاعاتي

قوانين دستيابي به بانك هاي اطلاعاتي خيلي سرراست و مشخص است ولي به دليل عدم رعايت برخي نكات توسط طراحان و پياده كنندگان ممكن است كارآئي برنامه هاي وب كاهش و همزمان با افزايش كاربران امكان استفاده بهينه و مطلوب از برنامه وجود نداشته باشد .
قبل از بررسي اهم مطالب مرتبط با بكارگيري بانك هاي اطلاعاتي در برنامه هاي وب لازم است به اين نكته مهم اشاره گردد كه مي بايست يك اتصال به بانك اطلاعاتي را صرفا" در زماني كه به وجود آن نياز است ايجاد و در اولين فرصت ممكن آن را close كرد چراكه اولا" تعداد اتصالات به يك بانك اطلاعاتي محدود و ثانيا" مديريت آنها كار اضافه اي را نيز به سرويس دهنده تحميل خواهد كرد ( استفاده بهينه از يك منبع محدود ) .
با رعايت موارد زير مي توان كارآئي برنامه هاي وب را بهبود بخشيد :
• استفاده از stored procedure : سيستم هاي مديريت بانك هاي اطلاعاتي رابطه اي نظير SQL server پيچيدگي هاي خاص خود را دارند . سيستم هاي فوق، قادر به انجام كارهاي متنوعي هستند كه با استفاده از ASP.NET نمي توان آنها را انجام داد . بكارگيري اين نوع پتانسيل ها مي تواند تاثيرات گسترده اي را بر روي برنامه هاي وب به دنبال داشته باشد . به عنوان نمونه ، استفاده از stored procedure در مقابل Query هاي توليد شده پويا مي تواند تاثير غيرقابل انكاري بر روي كارآيي برنامه هاي وب داشته باشد چراكه stored procedure را مي توان براي استفاده آتي ترجمه و بهينه سازي كرد . تاثير استفاده از stored procedure در مواردي كه لازم است چندين عمليات مرتبط به هم در يك لحظه انجام شود ، بسيار مشهود و ملموس مي باشد .
• استفاده از پروفايلينگ و ايندكس : تعريف ايندكس ها بگونه اي كه با نوع جستجو و خواسته هاي مورد نياز در يك سيستم مطابقت نمايد ، مي تواند نتايج مورد نظر را با سرعت قابل قبولي در اختيار كاربران قرار دهد . براي بهينه سازي بي عيب ايندكس ها در يك بانك اطلاعاتي لازم است كه آنها را با استفاده از يك ابزار profiling ارزيابي كرد ( نظير SQL Server Profiler ) . اين نوع ابزارها فعاليت بانك اطلاعاتي را در يك لاگ خاص ثبت مي نمايند و در ادامه مي توان آن را بررسي ، آناليز و بر اساس نتايج بدست آمده در ايندكس ها تجديد نظر نمود . ابزارهاي فوق مي توانند مسائلي نظير اجراي كند query را شناسائي و حتي مجموعه اي جديد از ايندكس ها را كه داراي كارآئي بمراتب بهتري مي باشند ، پيشنهاد دهند . براي پروفايل بهتر بانك اطلاعاتي لازم است كه يك لود فرضي را بر روي برنامه شبيه سازي كرد.
• بازيابي صرفا" اطلاعات مورد نياز : يكي از ساده ترين روش هائي كه باعث بهبود هر نوع كد بانك اطلاعاتي مي گردد ، كاهش حجم اطلاعات بازيابي شده از بانك اطلاعاتي است . اين كار باعث كاهش لود شبكه ، مدت زمان لازم براي باز شدن اتصال و حجم نهائي صفحه مي گردد . به عنوان نمونه با استفاده از فيلترينگ مناسب در query ( نظير استفاده از تاريخ ) و بازيابي صرفا" فيلدهاي ضروري ، مي توان حجم داده بازيابي شده را حتي المقدور كاهش داد .
• استفاده از connection pooling : در يك برنامه وب عمومي ، سيستم مديريت بانك اطلاعاتي درخواست هاي بيشماري را از طرف سرويس گيرندگان براي صفحات وب متعدد دريافت مي نمايد . معمولا" اين اتصالات براي مدت زمان كوتاهي فعال و ايجاد آنها يكي از مراحل وقت گير در زمان پياده سازي است . در صورتي كه هر صفحه وب از connection string مشابه استفاده نمايد ، بانك هاي اطلاعاتي نظير SQL server قادر به استفاده از connection pooling تعبيه شده در خود براي استفاده مجدد از يك اتصال براي بيش از يك سرويس گيرنده متوالي مي باشند . بدين ترتيب امكان استفاده از connection string به دفعات فراهم مي گردد. اين كار بطرز چشمگيري باعث بهبود سرعت مي گردد . در چنين مواردي مي توان از فايل web.config براي ذخيره connection string استفاده تا امكان بكارگيري آنها در صفحات متعدد يك برنامه وب فراهم گردد.
• استفاده از date binding : سريعترين روش بازيابي و نمايش اطلاعات از يك بانك اطلاعاتي ، استفاده از يك DataReader و يا Dataset و نسبت دهي مستقيم آن به يك كنترل داده است . رويكرد فوق ممكن است به عمليات بيشتري جهت استفاده از تمپليت هاي سفارشي نياز داشته باشد ولي اين وضعيت بمراتب بهتر از حالتي است كه بطور دستي بين سطرها ( ركوردها ) حركت و آنها را در صفحه مورد نظر قرار داد.
• استفاده از caching : در صورتي كه مجموعه اي خاص از داده متناوبا" درخواست و بندرت تغيير مي يابد ، مي توان آنها را جهت استفاده آتي cache نمود . با استفاده از سيستم caching ، در اولين مرتبه اي كه يك سرويس گيرنده درخواست اطلاعات را مي نمايد ، اطلاعات درخواستي از بانك اطلاعاتي خوانده شده و در حافظه موقت قرار مي گيرند . بدين ترتيب امكان استفاده مستقيم از اطلاعات cache شده بدون ضرورت دستيابي به بانك اطلاعاتي فراهم مي گردد . در بخش هاي بعدي به بررسي Output caching و data caching خواهيم پرداخت .

session state

session state يكي از بزرگترين محدوديت هاي تاثير گذار در خصوص كارآئي برنامه هاي نوشته شده با استفاده از ASP كلاسيك است . با اين كه در ASP.NET ويژگي هاي جديدي به منظور بهبود كاركرد session state ارائه شده است ولي همچنان لازم است كه از آن با دقت استفاده گردد .
اگر صرفا" ID يك خريدار كالا را در session state ذخيره كرده باشيم، درگير مسائلي خاص نخواهيم شد . در چنين مواردي مي توان يك سبد خريد كالاي الكترونيكي را با ذخيره ليستي از محصولات انتخابي توسط خريدار ايجاد نمود . در صورتي كه قصد ذخيره حجم بالائي از اطلاعات نظير يك Dataset را داشته باشيم ، مي بايست در اين رابطه دقت و تاثير آن را بر روي موفقيت برنامه بررسي كرد . به عنوان نمونه ، در صورتي كه هر session فضائي به ميزان يك مگابايت را استفاده نمايد ، يكصد session همزمان باعث استفاده 100 مگابايت از حافظه خواهد شد .
براي حل اين نوع از مشكلات ، در زمان طراحي مي توان بر اساس يكي از دو گزينه هاي زير تصميم گيري نمود :
• ذخيره تمامي اطلاعات مورد نياز در يك ركورد بانك اطلاعاتي و ذخيره ID ركورد مورد نظر در يك session . روش فوق باعث صرفه جوئي در مصرف حافظه مي گردد ولي سرعت برنامه را كاهش خواهد داد ( با توجه به فرآيند دستيابي به بانك اطلاعاتي كه يكي از عناصر مهم و تاثيرگذار در خصوص كارآئي برنامه هاي وب است ) .
• به عنوان يك راه حل بهتر مي توان اطلاعات مورد نظر را در يك ركورد بانك اطلاعاتي ذخيره و در ادامه برخي از اطلاعات را در حافظه cache نمود . بدين ترتيب ، امكان بازيابي اطلاعات با سرعت بيشتري فراهم مي گردد . در بخش هاي بعدي با data caching بيشتر آشنا خواهيم شد .
بهترين روش و يا گزينه براي ذخيره session ، استفاده از روش in-process است كه به صورت پيش فرض در نظر گرفته مي شود . براي ذخيره session مي توان از روش هاي ديگري نظير يك بانك اطلاعاتي SQL نيز استفاده نمود . استفاده از روش فوق پردازش هاي بيشتري را به سيستم تحميل و صرفا" در مواردي كه وب سايت مورد نظر در يك web farm به همراه چندين سرويس دهنده هاست شده باشد ، توصيه مي گردد .
محور دوم : تست برنامه قبل از عملياتي شدن آن و يا پروفايلنگ ( Profiling )
براي قضاوت در خصوص تلاش هاي انجام شده در ارتباط با بهبود كارآئي يك برنامه وب ، مي بايست قادر به سنجش كارآئي آن در عمل باشيم . در مواردي كه كارآئي يك برنامه كند و نااميد كننده است ، مي بايست بر اساس اطلاعات كافي اقدام به شناسائي گره ها و عوامل تاثير گذار بر روي كارآئي برنامه هاي وب نمائيم تا از اين رهگذر بتوانيم مشكل و يا مشكلات را برطرف و يك برنامه وب كارآ را آماده استفاده عملياتي و نهائي نمائيم .
يكي از مسائل مهم در ارتباط با برنامه هاي وب ، عدم تست آنها با شرايط مشابه و يا نزديك به محيط واقعي است . در اين راستا مي توان از نرم افزارها و يا ابزارهاي مختلفي استفاده كرد تا بتوان عملكرد و سرويس دهي يك برنامه وب را قبل از زير بار رفتن واقعي مشاهده و بررسي نمود .
براي قضاوت در خصوص تلاش هاي انجام شده در ارتباط با بهبود كارآئي يك برنامه وب ، مي بايست قادر به سنجش كارآئي آن در عمل باشيم . در مواردي كه كارآئي يك برنامه كند و نااميد كننده است ، مي بايست بر اساس اطلاعات كافي اقدام به شناسائي گره ها و عوامل تاثير گذار بر روي كارآئي برنامه هاي وب نمائيم تا از اين رهگذر بتوان مشكل و يا مشكلات را برطرف و يك برنامه وب كارآ را آماده استفاده عملياتي و نهائي كرد .
شركت مايكروسافت در اين رابطه ابزارها و برنامه هاي متعددي را ارائه نموده است كه در ادامه به بررسي آنها خواهيم پرداخت .

Stress Testing

پياده كنندگان برنامه هاي وب مي توانند از ابزارهاي تست متعدد به همراه برخي امكانات ارائه شده در فريمورك دات نت براي پروفايل كردن برنامه هاي ASP.NET استفاده نمايند . اغلب ، گذر از مرحله تست و اعمال يك پل ارتباطي بين نتايج تست و برنامه وب كار زمان گيري است . به عنوان نمونه ممكن است در مرحله تست بتوان اطلاعات مهمي نظير TTFB ( برگرفته شده از Average Time to first byte ) كه نشان دهنده مدت زمان ارسال درخواست و دريافت اولين بايت از سرويس دهنده است و يا TTLB ( برگرفته شده از Average Time to last byte ) كه نشان دهنده زمان ارسال درخواست و دريافت آخرين بايت از سرويس دهنده است را ركورد و ثبت نمود . ولي بدون استفاده از يك روش دقيق و صحيح اندازه گيري ، تشخيص پارامترهاي تاثيرگذار در كاهش كارآئي يك برنامه وب كار مشكلي خواهد بود .
به عنوان مثال ، كاهش كارآئي يك برنامه وب ممكن است مربوط به سرعت پائين هارد ديسك ، تنظيمات ضعيف ASP.NET ، عدم طراحي صحيح بانك اطلاعاتي و يا عدم طراحي مناسب برنامه باشد . در واقع‌، تست كارآئي علم و دانش مختص به خود را دارد .
براي انجام اكثر تست هاي اوليه ، مي توان از يك سرويس دهنده اختصاصي و مجموعه اي از سرويس گيرندگان استفاده نمود كه از طريق يك شبكه سريع ايزوله شده با سرويس دهنده وب تعامل برقرار مي نمايند . بدين منظور مي توان از يك ابزار توليد load كه بطور اتوماتيك مجموعه اي ‌از صفحات را از سرويس دهنده درخواست مي نمايد استفاده كرد تا يك لود سنگين شبيه سازي گردد . ACT ( برگرفته شده از Application Center Test ) و WAST ( برگرفته شده از Web Applications Stress Tool ) دو نمونه متداول در اين زمينه مي باشند .
با استفاده از ابزارهاي فوق مي توان شرايط حاكم بر يك برنامه وب در دنياي واقعي را شبيه سازي نمود ( تداوم درخواست صفحات از طريق چندين اتصال همزمان ) . اكثر ابزارهاي توليد load ، فعاليت ها و كارهائي را كه انجام مي دهند ثبت مي نمايند تا امكان بررسي آنها توسط طراحان و پياده كنندگان وجود داشته باشد .
علاوه بر برنامه هاي فوق ، مي توان نتايج را با استفاده از Windows performance counters ثبت و مشاهده كرد .

performance counter

برنامه performance counters ويندوز يكي از ابزارهاي متداول موجود براي اندازه گيري كارآئي يك برنامه مي باشد . با استفاده از برنامه فوق مي توان به تعداد دلخواه counter را اضافه و يا مستقيما" كارآئي را از طريق جعبه محاوره اي system performance اندازه گيري كرد .
براي فعال كردن برنامه فوق مي توان از مسير Settings|Control Panel |Administrative Tools |Performance استفاده كرد. اين برنامه به صورت پيش فرض صرفا" كارآئي پردازشگر اصلي سيستم و ديسك را اندازه گيري مي نمايد .
پس از نصب ASP.NET ، مجموعه اي counter مفيد براي رديابي و ارزيابي كارآئي برنامه هاي وب نيز نصب مي گردد . براي اضافه كردن counter ، با كليك (سمت راست) بر روي ليست counter و انتخاب properties ، مي توان گزينه هاي مختلفي را پيكربندي نمود ( نظير تغيير شكل ظاهري نمودار و نحوه ثبت اطلاعات در قالب يك گزارش ) .
يكي از مهمترين گزينه ها بخش مربوط به Data است كه با استفاده از آن مي توان به ليست موجود يك counter را اضافه و يا از آن حذف نمود . براي شروع ، مي توان تمامي كانتر هاي پيش فرض را حذف و با استفاده از گزينه Add موارد دلخواه را به ليست اضافه نمود .
در جعبه محاوره اي Add Counter ، چندين ويژگي مهم از جمله امكان مشخص كردن نام كامپيوتر وجود دارد . به عبارت ديگر ، شما مي توانيد كارآئي يك كامپيوتر راه دور را مانيتور نمائيد . مانيتورينگ كارآئي سرويس دهنده وب از طريق يك سرويس گيرنده ايده آل است چراكه احتمال تاثير عملكرد مانيتورينگ بر روي سرويس دهنده از بين خواهد رفت . ويژگي مهم بعدي ، performance object است كه با استفاده از آن مي توان يك گروه counter را متناسب با شي مورد نظر انتخاب نمود . گروه ASP.NET اطلاعات كاملي را در خصوص كارآئي كلي برنامه هاي ASP.NET ارائه مي نمايد . اين در حالي است كه گروه ASP.NET Application اطلاعاتي را در رابطه با يك برنامه وب خاص ارائه مي نمايد .
برخي از انواع مفيد كانترها به همراه گروه ، نام counter و عملكرد هر يك از آنها در جدول 1 نشان داده شده است .
سطرهاي ستاره دار، كانترهائي را مشخص مي نمايد كه با استفاده از آنها مي توان اشكال زدائي يك مسئله را انجام داد . ساير سطرها ، كانترهائي را نشان مي دهد كه استفاده از آنها همواره مفيد مي باشد .

 

گروه

counter

عملكرد

processor

% CPU Utilization

درصد استفاده از CPUرا نشان مي دهد . در صورتي كه استفاده از CPUدر يك بازه زماني صرفنظر از loadسرويس گيرنده ثابت باقي بماند ، نشان دهنده انتظار يك برنامه براي استفاده از يك منبع محدود است .  

ASP.NET

Requests Queued

تعداد درخواست هاي در انتظار پردازش را مشخص مي نمايد . از counterفوق براي مشخص كردن حداكثر loadسرويس دهنده وب استفاده مي گردد .

ASP.NET

* Application Restarts ,
Worker Process Restarts

تعداد دفعاتي كه پردازه ASP.NETراه اندازي مجدد و يا resetمي گردد را مشخص مي نمايد . اين counterنشاندهنده بروز مسائل ناخواسته است.

ASP.NET Applications

Requests/Sec

حداكثر توان عملياتي برنامه وب را مشخص مي نمايد .

ASP.NET Applications

* Errors Total

تعداد خطاء توليد شده توسط يك برنامه وب را مشخص مي نمايد . مقدار اين counterدر عمل مي بايست صفر و يا نزديك به صفر باشد .

ASP.NET Applications

Pipeline Instance Count

تعداد درخواست pipelineيك برنامه را مشخص مي نمايد و از آن براي مشخص شدن حداكثر درخواست همزماني كه مي توان به آنها پاسخ داده شود ، استفاده مي گردد .
در صورتي كه مقدار اين counterتحت يك loadپائين باشد ، نشان دهنده استفاده مطلوب از CPUاست . 

System

* Context Switches/sec

پارامتر فوق تعداد دفعات سوئيچينگ thread contextرا نشان مي دهد . در صورتي كه مقدار اين پارامتر زياد باشد ،  threadهاي مختلف براي استفاده از  يك منبع محدود با يكديگر رقابت مي نمايند .

جدول 1 : ليست برخي كانترهاي مفيد

دستيابي به كلاس هاي performance counters از طريق كد

با توجه به اين كه ASP.NET بخشي از فريمورك دات نت است ، پياده كنندگان برنامه هاي وب مي توانند در صفحات وب نوشته شده با استفاده از فناوري ASP.NET به تمامي كلاس هاي موجود در فريمورك دات نت دستيابي داشته باشند . اين بدان معني است كه از طريق يك صفحه وب ASP.NET مي توان عمليات متعددي نظير پردازش تصاوير ، نوشتن در event log و يا خواندن و انعكاس performance counters در خروجي را انجام داد . گرچه استفاده از امكاناتي از اين قبيل ممكن است چالش هاي امنيتي مختص به خود را دارا باشد ولي با رعايت نكات ايمني مي توان پتانسيل برنامه هاي وب را در جهت ارائه خدمات مطلوب و بهينه به كاربران افزايش داد .
به عنوان نمونه مي توان يك performance counter جديد را اضافه و يا مقدار متناظر با يك performance counter را بازيابي و در ادامه آن را در يك صفحه وب و يا يك برنامه desktop نمايش داد .
براي استفاده از پتانسيل فوق ، از namespace با نام System.Diagnostics استفاده مي گردد . ليست برخي از كلاس هاي دات نت به منظور تعامل با performance counter در جدول 2 نشان داده شده است .

 

كلاس

عملكرد

PerformanceCounter

ارائه يك  counterخاص كه شامل اطلاعاتي نظير نام counterو نوع داده ئي است كه مي بايست ثبت گردد .

PerformanceCounterCategory

يك گروه counterرا  كه شامل يك و يا چندين counterاست ، مشخص مي نمايد .

CounterCreationData

ارائه داده مورد نياز براي ايجاد يك counterجديد .

CounterSample

ارائه مجموعه اي از اطلاعات ثبت شده توسط counter.
در اين رابطه يك RawValue( شماره ثبت شده ) ، يك TimeStamp( زماني كه مقدار ثبت شده است ) و اطلاعات اضافه اي در رابطه با نوع counterو نحوه خواندن آن را ارائه مي نمايد .

جدول 2 : ليست برخي كلاس هاي دات نت براي كار با Performance counter
مثال : نمايش ظرفيت آزاد حافظه فيزيكي در يك صفحه وب
در كد فوق ، ظرفيت آزاد حافظه فيزيكي بر حسب مگابايت در صفحه وب نمايش داده مي شود . براي انجام اين كار ، در ابتدا يك نمونه از كلاس PerformanceCounter به همراه نام گروه Memory و counter با نام Available MBytes ايجاد شده است . براي ايجاد يك نمونه از كلاس PerformanceCounter از كد زير استفاده شده است

 Dim perfFreeMem as New PerformanceCounter("Memory", "Available MBytes")

بدين ترتيب يك شي با نام perfFreeMem ايجاد كه Performance counter مورد نظر را ارائه مي نمايد . براي خواندن مقدار جاري counter از متد NextValue استفاده مي گردد تا مقدار بعدي Performance counter را برگرداند . با نسبت دادن مقدار برگردانده شده به خصلت Text كنترل سرويس دهنده Label ، امكان مشاهده آن در خروجي فراهم مي گردد .

<%@ Import Namespace = System.Diagnostics %>
<script runat="server">
  sub Page_Load(sender as Object, e as EventArgs)
     Dim perfFreeMem as New PerformanceCounter("Memory", "Available MBytes")
     lblFreeMem.Text = perfFreeMem.NextValue()
  end sub
</script>

Free Memory (in MB):
<asp:Label id="lblFreeMem" runat="server" />

مراحل انجام كار در مثال فوق به شرح زير است :
• مرحله اول : استفاده از namespace با نام System.Diagnostics در ابتداي برنامه
• مرحله دوم : ايجاد و مقداردهي مناسب يك نمونه از كلاس PerformanceCounter تا قادر به خواندن counter با نام Available MBytes از گروه Memory باشد .
• مرحله سوم : نسبت دادن مقدار برگردانده شده توسط متد NextValue به خصلت Text كنترل سرويس دهنده label با نام lblFreeMem
در اين بخش به بررسي امكانات caching در ASP.NET 2.0 خواهيم پرداخت .

مفاهيم اوليه Caching

Caching از جمله واژه هاي كاملا" آشنا در عرصه فناوري اطلاعات و ارتباطات است . اين واژه ريشه فرانسوي‌ دارد و به معني ذخيره سازي است . در دنياي پردازش اطلاعات ، به ذخيره اطلاعات براي استفاده آتي اطلاق مي گردد .در واقع ، Caching فرآيندي است كه بر اساس آن داده با فركانس استفاده بالا به منظور پاسخ به درخواست هاي بعدي ذخيره مي گردد. اطلاعات ذخيره شده ممكن است در آينده مجددا" استفاده گردند و يا اين احتمال وجود خواهد داشت كه هرگز شرايط استفاده مجدد از آنها فراهم نگردد . بنابراين Cache صرفا" زماني مفيد خواهد بود كه هزينه ذخيره اطلاعات كمتر از هزينه بازيابي و يا محاسبه مجدد آنها باشد .
امروزه از مفهوم Caching در زمينه هاي متعددي در سيستم هاي كامپيوتري و شبكه اي استفاده مي گردد . پردازنده هاي كامپيوتر داراي cache اختصاصي براي داده و دستورالعمل ها مي باشند . سيستم هاي عامل داراي بافرهاي cache براي سيستم هاي فايل و درايوها مي باشند . سيستم هاي فايل توزيع شده ( شبكه اي ) نظير NFS ( برگرفته شده از network file system ) و AFS ( برگرفته شده از Andrew File System ) براي بهبود كارآئي خود از cache استفاده مي نمايند . روترهاي بكارگرفته شده در ستون فقرات شبكه اينترنت مسيرهائي را كه اخيرا" از آنها استفاده كرده اند ، cache مي نمايند . سرويس دهندگان DNS ، ماحصل فرآيند ترجمه نام به آدرس را جهت استفاد آتي cache مي نمايند .
برنامه هاي كامپيوتري خصوصا" برنامه هاي وب نيز از اين فناوري در ابعاد گسترده اي استفاده مي نمايند تا بتوانند با سرعت بيشتر پاسخگوي نياز كاربران و مخاطبان خود باشند . به عنوان نمونه ، مرورگر با ارائه پتانسل هاي لازم سمت سرويس گيرنده امكان caching متن و يا تصاوير را فر اهم مي نمايد و در سمت سرويس دهنده با استفاده از امكانات متعددي مي توان بهترين گزينه caching را به منظور افزايش كارائي انتخاب كرد.
در صورتي كه از روش هائي مناسب به منظور پياده سازي سيستم Caching در برنامه هاي كامپيوتري استفاده گردد ، كارائي و توانمندي آنها در جهت ارائه خدمات به كاربران بطرز محسوسي افزايش خواهد يافت .

روش هاي caching در ASP.NET

با عرضه ASP.NET 2.0 تحولات گسترده اي در خصوص cache ايجاد گرديد . پياده كنندگان برنامه هاي وب با آشنائي و بكارگيري پتانسيل هاي موجود مي توانند برنامه هاي وب با كارآئي مطلوب را پياده سازي نمايند .
در ASP.NET از دو نوع سيستم caching استفاده مي گردد . پياده كنندگان برنامه هاي وب مي توانند و شايد بهتر باشد بگوئيم مي بايست از دو سيستم فوق در جهت افزايش كارآئي برنامه هاي خود استفاده نمايند ، چراكه دو سيستم فوق مكمل يكديگر مي باشند .
• Output caching ، ساده ترين روش caching است . صفحات aspx . بر اساس فرآيندي در سمت سرويس دهنده ترجمه و پس از اجراء ، ماحصل خروجي آنها به صورت يك صفحه html براي سرويس گيرنده ارسال مي گردد . در اين روش يك نسخه نهائي از صفحه ترجمه شده html كه براي سرويس گيرنده ارسال شده است ، cache مي گردد . بدين ترتيب ، زماني كه سرويس گيرنده بعدي درخواست خود براي استفاده از اين صفحه را براي سرويس دهنده ارسال مي نمايد ، در مقابل اجراي صفحه و توليد خروجي لازم ( انجام پردازش هاي سمت سرويس دهنده با توجه به ماهيت و جايگاه عملكردي يك صفحه در يك برنامه وب ) ، صفحه ترجمه شده html بطور اتوماتيك براي وي ارسال مي گردد . بدين ترتيب ، مدت زماني كه لازم است صفحه به همراه كد درون آن ترجمه و اجراء گردد بطور كامل حذف مي گردد .
• Data caching : براي استفاده از اين روش مي بايست بطور دستي و از طريق كد شرايط آن را فراهم نمود . پياده كنندگان مي توانند بخش هاي مهمي از اطلاعات را كه زمان زيادي صرف ساختن آنها شده است ( نظير يك DataSet بازيابي شده از يك بانك اطلاعاتي ) را در cache ذخيره نمايند . در ادامه ، ساير صفحات مي توانند وجود اين اطلاعات را بررسي و در صورت موجود بودن در cache از آنها استفاده نمايند . بدين ترتيب ، مراحل مورد نياز براي بازيابي اطلاعات حذف خواهد شد .
روش فوق از لحاظ مفهومي شباهت زيادي به استفاده از application state دارد ولي داراي قابليت هاي بيشتري در سمت سرويس دهنده است . به عنوان نمونه زماني كه حجم داده بگونه اي زياد گردد كه كارآئي يك برنامه را تحت تاثير قرار دهد ، آيتم هاي موجود در cache بطور اتوماتيك از cache حذف خواهند شد . براي ذخيره آيتم ها در cache مي توان يك تاريخ را مشخص تا پس از سپري شدن زمان مورد نظر بطور اتوماتيك از حافظه حذف گردند .
علاوه بر روش هاي كلي فوق ، دو نوع خاص ديگر از caching بر اساس مدل هاي اشاره شده نيز ايجاد شده است :
• Fragment caching : روش فوق نوع خاصي از output caching است و در مقابل caching كد Html براي تمامي صفحه ، صرفا" بخش هائي خاص از كد cache مي گردد. در اين روش خروجي كد ترجمه شده Html مربوط به يك كنترل كاربر بر روي يك صفحه ذخيره مي گردد . بدين ترتيب در صورت اجراء مجدد صفحه ، كد موجود در صفحه اجراء‌ مي گردد و ضرورتي به اجراء كد مرتبط با كنترل كاربر نخواهد بود .
• Data source caching : اين نوع caching بر اساس كنترل هاي منبع داده ايجاد و شامل كنترل هاي منبع داده ObjectDataSource ، SqlDataSource و XmlDataSource مي باشد. از لحاظ فني ، در روش فوق از data caching استفاده مي گردد. تنها تفاوت موجود در اين رابطه ، عدم نياز به انجام پردازش هاي مورد نياز توسط پياده كننده است . بدين منظور لازم است كه برخي خصلت ها و پيام هاي كنترل منبع داده كه مسئوليت ذخيره و بازيابي caching را برعهده دارند ،‌ توسط پياده كنندگان پيكربندي گردد.
در اين بخش و ساير بخش هاي بعدي به ترتيب به بررسي موارد زير خواهيم پرداخت :
• output caching
• data caching
• caching در كنترل هاي منبع داده
• SQL cache dependency

نحوه استفاده از output caching

با استفاده از output caching ، نسخه نهائي كد ترجمه شده Html صفحه cache مي گردد . زماني كه صفحه مجددا" و توسط كاربر ديگر درخواست مي گردد ، اشياء ايجاد نخواهند شد . همچنين ، چرخه حيات صفحه آغاز نخواهد شد و هيچگونه كدي اجراء نمي گردد . در مقابل ، كد cache شده در اختيار متقاضيان بعدي قرار داده مي شود . با توجه به اين كه در روش output caching هزينه هاي بالا سري كد ( پردازش هاي اضافه ) حذف مي گردد ، كارآئي برنامه بطرز محسوسي افزايش خواهد يافت .
براي آشنائي با نحوه عملكرد output caching ، كد زير را كه زمان و تاريخ جاري سيستم را در خروجي نشان مي دهد ، بررسي مي نمائيم .

 

 <%@ OutputCache Duration="20" VaryByParam="None" %>
<script runat="server">
  sub Page_Load(sender as Object, e as EventArgs)
    lblDate.Text = "The time is now:<br />"
    lblDate.Text &= DateTime.Now.ToString()
  end sub
</script>
<asp:Label id="lblDate" runat="server" />

متداولترين روش caching يك صفحه ASP.NET ، درج دايركتيو OutputCache در ابتداي فايل aspx . است . كد زير نحوه استفاده از دايركتيو فوق را نشان مي دهد :

 <%@ OutputCache Duration="20" VaryByParam="None" %>

در دايركتيو فوق از دو خصلت Duration و VaryByParam استفاده شده است . خصلت Duration به ASP.NET اعلام مي نمايد كه صفحه را به مدت 20 ثانيه cache نمايد. خصلت VaryByParam ميزان وابستگي فرآيند caching را به يك و يا چندين پارامتر مشخص مي نمايد . در برخي موارد ممكن است اين وابستگي مهم نباشد و مقدار آن None در نظر گرفته شود ( همانند مثال فوق ) .
پس از ذخيره كد فوق در فايلي با نام CacheExample1.aspx و اجراء آن ، نتايج جالب و قابل توجه اي را مشاهده خواهيم كرد . اولين مرتبه اي كه صفحه درخواست مي گردد ، تاريخ و زمان جاري در خروجي نمايش داده مي شود .در صورتي كه پس از گذشت مدت زمان بسيار كوتاهي صفحه را refresh نمائيم ، خروجي صفحه بهنگام نخواهد شد . در مقابل ، ASP.NET بطور اتوماتيك خروجي نسخه cache شده را ارسال خواهد كرد . وضعيت فوق به مدت 20 ثانيه ادامه خواهد يافت و پس از اتمام تاريخ مصرف نسخه cache شده ، ASP.NET مجددا" كد صفحه را اجراء و يك نسخه جديد cache را ايجاد و از آن به مدت 20 ثانيه ديگر استفاده خواهد كرد .
شايد بنظر 20 ثانيه زمان زيادي نباشد ولي براي سايتي كه حاوي اطلاعات گسترده اي جهت ارائه به كاربران متعدد است ، اين موضوع مي تواند كاملا" متفاوت باشد. به عنوان نمونه ، فرض كنيد مي خواهيم ليستي از محصولات قابل عرضه به كاربران را در يك صفحه نمايش دهيم . با caching صفحه به مدت 20 ثانيه ، دستيابي به بانك اطلاعاتي محدود به سه عمليات در يك دقيقه مي گردد . بدون caching ، براي هر كاربري كه متقاضي مشاهده ليست محصولات است ، مي بايست فرآيند ارتباط با بانك اطلاعاتي و نمايش محصولات در يك ساختار نمايشي مناسب ( نظير Gridview ) انجام شود . بديهي است با caching صفحه به مدت 20 ثانيه امكان پاسخگوئي به ده ها درخواست در مدت زمان فوق و بدون نياز به دنبال كردن فرآيند ارتباط با بانك اطلاعاتي و نمايش داده انجام مي شود .
توجه داشته باشيد كه اگر مدت زمان حضور يك نسخه cache در حافظه 20 ثانيه تعيين شده باشد ، اين بدان معني نخواهد بود كه واقعا" در طي مدت زمان فوق نسخه cache شده در حافظه وجود خواهد داشت . صفحه مورد نظر ممكن است در اولين فرصتي كه سيستم به منظور انجام كارهاي اساسي تر خود با كمبود حافظه مواجه شود از آن خارج گردد . بدين ترتيب ، پياده كنندگان مي توانند با خيالي آسوده از cache استفاده نمايند بدون اين كه نگران تاخير در اجراي برنامه به دليل استفاده از عنصر حياتي حافظه توسط cache باشند.
زماني كه يك صفحه cache شده مجددا" ترجمه مي گردد ، ASP.NET بطور اتوماتيك صفحه را از cache خارج مي نمايد . بدين ترتيب از بروز مسائلي نظير عدم وجود نسخه بهنگام شده در cache ممانعت بعمل مي آيد .
در زمان تست برنامه بهتر است كه caching غير فعال گردد . در زمان استفاده از روش ها و تكنيك هاي اشكال زدائي نظير متغيرهاي watch و يا ايجاد نقاط breakpoint ممكن است با مشكلاتي‌ مواجه شويم . در چنين مواردي در صورتي كه يك نسخه cache شده از صفحه در دسترس باشد ، كد مرتبط با آن در زمان اشكال زدائي اجراء نخواهد شد .

Caching سمت سرويس گيرنده

يكي ديگر از گزينه ها ، cache صفحه در سمت سرويس گيرنده است . در اين روش ، مرورگر نسخه اي از صفحه را ذخيره و بطور اتوماتيك از آن در مواردي كه دكمه back مرورگر كليك و يا آدرس URL صفحه مجددا" تايپ شود، استفاده مي نمايد . در صورتي كه كاربر دكمه Refresh را فعال نمايد ، از نسخه cache شده صرفنظر و صفحه مجددا" از سرويس دهنده درخواست مي گردد .
براي cache يك صفحه در سمت سرويس گيرنده از خصلت Location در دايركتيو OutputCache استفاده مي گردد . مقدار پيش فرض اين خصلت server است و مي تواند مقادير ديگر نظير Client ، None و Any را به آن نسبت داد .

 

 <%@ OutputCache Duration="20" VaryByParam="None" Location="Client" %>

استفاده از caching سمت سرويس گيرنده بمراتب كمتر از caching سمت سرويس دهنده است چراكه صفحه همچنان براي هر كاربر خاص مجددا" ايجاد خواهد شد . در روش فوق ، شاهد كاهش مدت زمان اجراء كد و يا دستيابي به بانك اطلاعاتي در جهت بهبود كارآئي برنامه نخواهيم بود . از روش caching سمت سرويس گيرنده در موارد خاصي نظير زماني كه صفحه cache شده حاوي داده سفارشي و مختص به يك كاربر است ، استفاده مي گردد .
در صورتي كه هر كاربر در يك session مجزاء فعاليت مي نمايد ، صفحه يك مرتبه ايجاد و تمامي سرويس گيرندگان از آن استفاده خواهند كرد . در چنين وضعيتي ممكن است عملكرد يك صفحه با مشكل مواجه گردد ( نظير نمايش يك پيام خوش آمدگوئي به كاربر و بر اساس نام آن ) . در مقابل ، مي توان از fragment caching براي caching بخش هائي خاص از صفحه و يا caching سمت سرويس گيرنده به منظور ذخيره نسخه مختص يك كاربر بر روي كامپيوتر هر يك از سرويس گيرندگان استفاده نمود.

Caching و Query string

يكي از نكات مهم در خصوص caching ، تصميم در خصوص زمان استفاده مجدد از صفحه و صحت اطلاعات است . اغلب پياده كنندگان تمايل زيادي در ارائه اطلاعات به صورت بلادرنگ دارند و كمتر در انديشه استفاده بهينه از سيستم caching مي باشند . پياده كنندگان مي توانند بدون نگراني در موارد متعددي از caching استفاده نمايند تا كارآئي برنامه هاي وب را افزايش دهند .
در مواردي كه اطلاعات به صورت پويا توليد مي گردد وضعيت caching و يا استراتژي ايجاد و بكارگيري مجدد آن تا اندازه اي متفاوت خواهد بود . به عنوان نمونه ، در صورتي كه در صفحه اي از session كاربر جاري استفاده مي شود تا بر اساس آن رابط كاربر سازماندهي گردد ، caching تمام صفحه مناسب نخواهد بود چراكه يك صفحه مشابه نمي تواند براي ساير كاربران مفيد و قابل استفاده مجدد باشد . يك نمونه ديگر ، صفحه اي است كه اطلاعات دريافتي خود را از يك صفحه ديگر و از طريق query string دريافت مي نمايد . در چنين مواردي صفحه به صورت پويا ايجاد و براي caching آن مي بايست از راهكارهائي ديگر استفاده گردد.
در مثال اشاره شده در بخش چهارم به خصلت VaryByParam دايركتيو OutputCache ، مقدار None نسبت داده شده بود . بدين ترتيب به ASP. NET اعلام شده است كه صرفا" يك نسخه از صفحه را cache نمايد تا بتوان از آن در تمامي حالات استفاده مجدد نمود . در چنين مواردي اگر درخواست صفحه به همراه اضافه كردن آرگومان هاي query string به URL باشد ، صرفا" از همان يك نسخه cache شده بدون توجه به مقدار آرگومان هاي دريافتي استفاده مي گردد ( تا زماني كه تاريخ مصرف نسخه cache شده به اتمام نرسيده باشد ) . شما مي توانيد اين موضوع را با اضافه كردن يك آرگومان query string بطور دستي در مرورگر انجام دهيد . مثلا" سعي كنيد صفحه را با افزودن a=b ? در انتهاي URL اجراء نمائيد. مشاهده خواهيد كرد كه خروجي cache شده همچنان يكسان خواهد بود .
با توجه به نتايج فوق ممكن است اينگونه برداشت شود كه output caching براي صفحه اي كه از آرگومان هاي query string استفاده مي نمايد ، مناسب نباشد . در اين رابطه ASP.NET يك راه حل ديگر را ارائه نموده است . در چنين مواردي مي توان خصلت VaryByParam را "*" در نظر گرفت تا مشخص گردد كه صفحه از query string استفاده مي نمايد و به ASP.NET اعلام گردد كه نسخه هاي cache مجزاء را براي مقادير مختلف آرگومان query string ذخيره نمايد .

 

 <%@ OutputCache Duration="20" VaryByParam="*" %>

بدين ترتيب زماني كه صفحه به همراه اطلاعات query string درخواست شود ، در ابتدا ASP.NET مقدار query string را بررسي مي نمايد . در صورتي كه رشته دريافتي با درخواست قبلي مطابقت نمايد و يك نسخه cache شده از صفحه موجود باشد ، از آن استفاده خواهد كرد . در غير اينصورت يك نسخه جديد از صفحه ايجاد و بطور جداگانه cache مي گردد .
براي آشنائي بهتر با نحوه عملكرد فرآيند فوق ، فرض كنيد مجموعه اي از درخواست ها به ترتيب زير دريافت گردد:
• كاربري صفحه اي را بدون پارامتر query string درخواست و نسخه A صفحه را دريافت مي نمايد .
• كاربري صفحه را با پارامتر ProductID=1 درخواست و نسخه B صفحه را دريافت مي نمايد .
• كاربر ديگر صفحه را با پارامتر ProductID=2 درخواست و نسخه C صفحه را دريافت مي نمايد .
• كاربر ديگر صفحه را با پارامتر ProductID=1 درخواست مي نمايد . در صورتي كه تاريخ اعتبار نسخه B كه قبلا" cache شده است به اتمام نرسيده باشد ، اين نسخه براي وي ارسال مي گردد.
• كاربر ديگر صفحه را بدون پارامتر درخواست مي نمايد . در صورتي كه تاريخ اعتبار نسخه A كه قبلا" cache شده است به اتمام نرسيده باشد ، اين نسخه براي وي ارسال مي گردد.
براي تست فوق و دريافت نتايج بهتر مي توان مدت زمان اعتبار نسخه cache شده را زياد كرد .
در صورتي كه صفحه اي صرفا" در ارتباط با داده سمت سرويس دهنده ( نظير داده موجود در يك بانك اطلاعاتي ) و يا داده موجود در query string باشد ،‌ بدون نگراني مي توان از روش output caching استفاده كرد .
در صورتي كه خروجي صفحه وابسته به اطلاعات خاص و مرتبط با كاربر نظير داده session و يا كوكي باشد ، از روش output caching نمي توان استفاده نمود چراكه مكانيزمي وجود ندارد كه بر اساس آن بتوان تفاوت caching را بر اساس session و يا كوكي تشخيص داد. output caching همچنين با صفحات پويائي كه محتويات خود را در پاسخ به رويدادهاي مرتبط با كنترل ها تغيير مي دهند كار نمي كند . در چنين مواردي ، مي توان از fragment caching براي caching يك بخش خاص از صفحه و يا از data caching براي caching اطلاعات خاص استفاده كرد.

caching با پارامترهائي خاص

بندرت مقدار VaryByParam معادل "*" در نظر گرفته مي شود و در اكثر موارد بهتر است كه يك متغير query string مهم را با نام مشخص كرد . كد زير نحوه انجام اين كار را نشان مي دهد.

 

 <%@ OutputCache Duration="20" VaryByParam="ProductID" %>

در چنين مواردي ، ASP.NET مقدار query string را بررسي و به دنبال پارامتر ProductID مي گردد . درخواست هائي با پارامترهاي مختلف ProductID بطور جداگانه cache و از ساير پارامترها صرفنظر خواهد شد .
در صورت لزوم مي توان چندين پارامتر را كه توسط semicolon از يكديگر جدا شده اند به خصلت VaryByParam نسبت داد . كد زير نحوه انجام اين كار را نشان مي دهد

در چنين مواردي ، ASP.NET نسخه هائي جداگانه از صفحه را با توجه به مقادير متفاوت ارائه شده توسط ProductID و CurrencyType در cache نگهداري خواهد كرد .

 <%@ OutputCache Duration="20" VaryByParam="ProductID;CurrencyType" %>

مثال : Caching چندين نسخه جداگانه از يك صفحه
در اين مثال از دو صفحه براي نشان دادن نحوه caching چندين نسخه جداگانه از يك صفحه وب استفاده شده است .

صفحه QueryStringSender.aspx

<%@ Page Language="VB" Culture="fa-IR" UICulture="fa-IR" %>
<Script Runat="Server">
  Protected Sub AnyButton_Click(ByVal sender As Object,ByVal e As System.EventArgs )
    Response.Redirect("QueryStringRecipient.aspx" &"?Version=" & CType(sender, Control).ID)
  End Sub
</Script>
<html dir="rtl">
<head >
<title>Caching Test</title>
</head>
<body style="font-family: Tahoma;">
  <form id="form1" runat="server">
    <div>
     <asp:Button ID="cmd1" runat="server" Text="نسخه شماره يك"
                        OnClick="AnyButton_Click" Width="133px" Font-Names="Tahoma" />
                       <br /><br />
     <asp:Button ID="cmd2" runat="server" Text="نسخهشماره دو"
                        OnClick="AnyButton_Click" Width="133px" Font-Names="Tahoma" />
                       <br /><br />
    <asp:Button ID="cmd3" runat="server" Text="نسخه شماره سه"
                       OnClick="AnyButton_Click" Width="133px" Font-Names="Tahoma" />
  </div>
  </form>
</body>
</html>

يك event handler ( با نام AnyButton_Click ) پس از كليك بر روي هر يك از سه دكمه موجود در صفحه فعال مي گردد . در روتين فوق پس از تشخيص اين كه بر روي كدام دكمه ( cmd2 ، cmd1 و cmd3 ) كليك شده است ، مقدار آن استخراج و به پارامتر Version نسبت داده مي شود و در نهايت كاربر به صفحه QueryStringRecipient.aspx هدايت مي گردد .
صفحه مقصد ( QueryStringRecipient.aspx ) يك پيام را متناسب با مقدار پارامتر Version در خروجي نمايش مي دهد . در صفحه فوق مقدار خصلت VaryByParam دايركتيو OutputCache معادل Version در نظر گرفته شده است.
(صفحه فوق به دنبال يك پارامتر query string با نام Version جهت ايجاد نسخه هاي جداگانه cache مي گردد ) .

 <%@ OutputCache Duration="20" VaryByParam="Version" %>

در صفحه QueryStringRecipient.aspx با توجه به مقدار پارامتر Version ، تاريخ و زمان جاري بر اساس يك فرمت خاص در خروجي نمايش و يك نسخه از آن نيز cache مي گردد .

صفحه QueryStringRecipient.aspx

<%@ Page Language="VB" Culture="fa-IR" UICulture="fa-IR" %>
<%@ OutputCache Duration="30" VaryByParam="Version" %>

<Script Runat="Server">
  Sub page_load ( )
   lblDate.Text = "زمان و تاريخ جاري:<br />" & DateTime.Now.ToString()
   Select Case Request.QueryString("Version")
    Case "cmd1"
       lblDate.Font.Size = FontUnit.XLarge
    Case "cmd2"
      lblDate.Font.Size = FontUnit.Large
    Case "cmd3"
      lblDate.Font.Size = FontUnit.Small
   End Select
 End Sub
</Script >

<html dir="rtl">
<head id="Head1" runat="server">
<title>Cache test</title>
</head>
 <body style="font-family: Tahoma;">
   <form id="form1" runat="server">
     <div>
          <asp:Label id="lblDate" runat="server" Font-Size="X-Large" Font-Bold="True"
                            EnableViewState="False"></asp:Label>
    </div>
  </form>
</body>
</html>

بدين ترتيب سه خروجي جداگانه Html ايجاد و با توجه به مدت زمان مشخص شده توسط خصلت Duration دايركتيو OutputCache جهت استفاده آتي cache مي گردند .

Custom Caching Control

براي ذخيره چندين نسخه cache از يك صفحه تنها گزينه موجود استفاده از پارامترهاي query string نمي باشد . ASP.NET به پياده كنندگان برنامه هاي وب امكان ايجاد رويه هائي سفارشي را مي دهد كه به كمك آنها مي توان در خصوص caching يك نسخه جديد از يك صفحه و يا استفاده از نسخه موجود تصميم گيري كرد .
كد نوشته شده در هر يك از رويه هاي فوق مناسب بودن اطلاعات را بررسي و يك رشته را برمي گرداند . در ادامه ، ASP.NET از رشته فوق براي پياده سازي caching استفاده مي نمايد. در صورتي كه كد مورد نظر رشته مشابهي را براي درخواست هاي مختلف توليد نمايد ، ASP.NET از نسخه cache شده صفحه استفاده خواهد كرد و در صورتي كه كد فوق يك مقدار جديد را توليد نمايد ، ASP.NET يك نسخه جديد cache را ايجاد و آن را بطور جداگانه ذخيره مي نمايد .
به عنوان نمونه فرض كنيد قصد داريم نسخه هاي مختلفي از يك صفحه را بر اساس نوع مرورگر cache نمائيم . بدين منظور در ابتدا از دايركتيو OutputCache در ابتداي صفحاتي كه قصد caching آنها را داريم استفاده كرده و در ادامه از خصلت VaryByCustom براي مشخص كردن يك نام كه نوع caching سفارشي را مشخص مي نمايد ، استفاده مي نمائيم .
با توجه به اين كه قصد داريم صفحات بر اساس مرورگر كاربران cache نمائيم ، در نمونه كد زير از نام Browser استفاده شده است .

 

<%@ OutputCache Duration="10" VaryByParam="None" VaryByCustom="Browser" %>

در ادامه نياز داريم رويه اي را كه رشته سفارشي caching را توليد مي نمايد ، ايجاد نمائيم . رويه فوق مي بايست در فايل پيكربندي global.asax و يا فايل code-behind مربوطه باشد .
كد زير نحوه انجام اين كار را نشان مي دهد .

رويه اي براي ايجاد سفارشي چندين نسخه cache از يك صفحه

 

رويه اي براي ايجاد سفارشي چندين نسخه cacheاز يك صفحه

Function GetVaryByCustomString(ByVal context As HttpContext, ByVal arg As String) As String

 If arg = "Browser"
    Dim BrowserName As String
    BrowserName = Context.Request.Browser.Browser
    Return BrowserName
 Else
    Return MyBase.GetVaryByCustomString(context, arg)
 End If
End Function
 

تابع GetVaryByCustomString يك رشته با مقدار VaryByCustom را از طريق پارامتر arg دريافت مي نمايد . بدين ترتيب مي توان برنامه اي را پياده سازي نمود كه چندين نوع از caching سفارشي را صرفا" در يك تابع مشابه پياده سازي نمايد . هر نوع از يك نام VaryByCustom مختلف استفاده مي نمايد ( نظير Browser ، BrowserVersion و يا DayOfWeek ) . تابع فوق مقدار VaryByCustom را از طريق آرگومان arg مشاهده و رشته caching مناسب را برمي گرداند . در صورتي كه رشته هاي caching براي درخواست هاي مختلف مطابقت نمايد ، ASP.NET از نسخه cache شده صفحه استفاده مي نمايد. در غير اينصورت ASP.NET براي هر رشته caching يك نسخه جداگانه را ايجاد ، ذخيره و cache مي نمايد .
دايركتيو OutputCache داراي يك خصلت سوم است كه از آن براي تعريف caching استفاده مي گردد . خصلت فوق كه VaryByHeader نام دارد ، به شما اجازه مي دهد كه نسخه هائي جداگانه از يك صفحه را بر اساس مقدار دريافتي يك HTTP header ذخيره نمائيد . در اين رابطه مي توان صرفا" يك header و يا مجموعه اي header كه توسط semicolon از يكديگر جدا شده اند را مشخص نمود . سايت هاي چند زباني مي توانند از روش فوق براي caching چندين نسخه از يك صفحه بر اساس زبان مرورگر سرويس گيرنده استفاده نمايند .
كد زير نحوه استفاده از خصلت VaryByHeader را نشان مي دهد .

 <%@ OutputCache Duration="20" VaryByParam="None" VaryByHeader="Accept-Language" %>

Fragment Caching

در برخي موارد ممكن است نتوان تمامي يك صفحه را cache نمود ولي همچنان اصرار داريم كه بخشي از صفحه را كه بندرت تغيير مي يابد ( نظير ليست كالاهاي موجود ) و هزينه زيادي صرف ايجاد آن شده است را cache نمائيم . در چنين مواردي مي توان از روش هاي متعددي نظير data caching ( در بخش بعد اين مقاله با روش استفاده از آنها آشنا خواهيم شد ) و fragment Caching استفاده كرد .
براي پياده سازي fragment Caching مي بايست براي بخشي از صفحه كه قصد caching آن را داريم يك كنترل كاربر را ايجاد و دايركتيو OutputCache را به آن اضافه كرد . بدين ترتيب علي رغم اين كه صفحه cache نخواهد شد ولي كنترل كاربر cache مي گردد .
fragment Caching از لحاظ مفهومي مشابه caching يك صفحه است و صرفا" داراي يك تفاوت اساسي است . در صورتي كه صفحه يك نسخه cache شده از يك كنترل كاربر را بازيابي نمايد ، نمي تواند با آن و از طريق كد ارتباط برقرار نمايد . به عنوان نمونه در صورتي كه كنترل كاربر خصلت هائي خاص را ارائه مي نمايد ، صفحه وب مورد نظر نمي تواند به اين خصلت ها دستيابي و آنها را تغيير دهد . توجه داشته باشيد ، زماني كه از يك نسخه cache شده كنترل كاربر استفاده مي گردد ، يك بلاك از تگ هاي Html درون صفحه قرار خواهند گرفت و در عمل شي كنترل كاربر در دسترس نخواهد بود .

Cache Profiles

يكي از مسائل در ارتباط با output caching قرار دادن كد درون صفحه است ( در بخش aspx markup . و يا در بخش كد كلاس ) . با اين كه استفاده و پيكربندي خصلت هاي مرتبط با دايركتيو OutputCache در صفحات وب ساده تر بنظر مي آيد ولي اين روش مي تواند مسائل مديريتي و پشتيباني مختص به خود را نيز به دنبال داشته باشد (خصوصا" اگر ده ها صفحه cache شده ايجاد شده باشد ) . به عنوان نمونه در صورتي كه قصد داشته باشيم تغييراتي را در خصوص caching تمامي صفحات فوق انجام دهيم ( مثلا" تغيير مدت زمان caching از 30 ثانيه به 60 ثانيه ) ، مي بايست هر صفحه بطور جداگانه تغيير و در ادامه نيز توسط ASP.NET مجددا" ترجمه گردند .
در ASP.NET 2.0 با معرفي يك راهكار جديد اين امكان در اختيار پياده كنندگان گذاشته شده است تا بتوانند از تنظيمات caching مشابه براي گروهي از صفحات استفاده نمايند . به ويژگي فوق cache profile مي گويند و به كمك آن مي توان تنظيمات caching را در يك فايل web.config تعريف نمود . بدين ترتيب ، اعمال تغييرات صرفا" از طريق يك نقطه فراهم مي گردد .
براي تعريف يك Cache Profile ، از تگ <add> در بخش <outputCacheProfiles> فايل web.config استفاده مي گردد . به cache profile ايجاد شده يك نام و مدت زمان مناسب نسبت داده مي شود . كد زير نحوه انجام اين كار را نشان مي دهد .

 

تعريف يك cache profileدر فايل web.config

<configuration>
   <system.web>
      <caching>
         <outputCacheSettings>
               <outputCacheProfiles>
                   <add name="ProductItemCacheProfile" duration="60" />
                </outputCacheProfiles>
          </outputCacheSettings>
     </caching>
...
   </system.web>
</configuration>

در ادامه مي توان از پروفايل فوق به كمك خصلت CacheProfile در يك صفحه استفاده نمود .

 <%@ OutputCache CacheProfile="ProductItemCacheProfile" VaryByParam="None" %>

در صورتي كه بخواهيم ساير جزئيات caching نظير VaryByParam را نيز مشخص نمائيم مي توان آن را به عنوان يك خصلت در دايركتيو OutputCache و يا تگ <add> در پروفايل مشخص نمود .

Output Caching در يك سرويس وب

از Output Caching مي توان براي متدهاي جداگانه در يك سرويس وب نيز استفاده كرد . براي انجام اين كار ، لازم است كه مقدار CacheDuration به WebMethod و قبل از تعريف متد اضافه گردد . كد زير نتايج يك متد وب را به مدت 30 ثانيه cache مي نمايد .

 

<WebMethod(CacheDuration:=30)> _
    Public Function MyMethod(ByVal myParameter As Integer) As String
    ...
    End Function

در اين بخش به بررسي data caching خواهيم پرداخت .

caching داده

caching داده ، انعطاف پذيرترين نوع caching است كه استفاده از آن مستلزم انجام مراحلي خاص در برنامه است . پياده كنندگان برنامه هاي وب مي توانند با استفاده از پتانسيل فوق آيتم هائي را كه هزينه ايجاد آنها گران است به شي cache اضافه نمايند .
cache يك خصلت از كلاس صفحه است و نمونه اي از كلاس System.Web.Caching.Cache را بر مي گرداند . عملكرد شي فوق شباهت زيادي با شي Application دارد ( نظير دستيابي به آن در تمامي صفحات توسط سرويس گيرندگان مختلف ) . علي رغم وجود شباهت هاي زياد ، دو شي Application و Cache داراي تفاوت هائي اساسي با يكديگر مي باشند :
• شي Cache از نوع thread-safe است . اين بدان معني است كه پياده كنندگان لازم نيست با صراحت عمليات lock و unlock شي cache را قبل از اضافه كردن و يا حذف يك آيتم از cache انجام دهند . به عنوان نمونه ، در صورت ايجاد يك شي سفارشي ممكن است در يك لحظه بيش از يك سرويس گيرنده قصد استفاده از آن را داشته باشند . در چنين مواردي اين احتمال وجود خواهد داشت كه شرايط استفاده از داده غيرمعتبر براي هر يك از سرويس گيرندگان فراهم گردد . براي غلبه بر محدوديت فوق مي توان از روش هاي مختلفي استفاده نمود . ايجاد يك نسخه ديگر از شي به منظور استفاده از آن در يك صفحه ، يكي از ساده ترين راهكارهاي موجود در اين زمينه است .
• آيتم هاي موجود در شي Cache بطور اتوماتيك از آن حذف مي گردند . ASP.NET يك آيتم را پس از اتمام مدت زمان اعتبار آن ، در صورت تغيير يكي از اشياء و يا فايل هاي وابسته و يا كمبود حافظه سرويس دهنده از cache خارج مي نمايد . اين بدان معني است كه پياده كنندگان مي توانند با خيالي آسوده از cache استفاده نمايند بدون اين كه نگران از دست دادن منبع ارزشمند حافظه باشند چراكه ASP.NET در صورت نياز آيتم ها را از حافظه خارج خواهد كرد . با توجه به اين كه همواره اين احتمال وجود دارد كه آيتم هاي ذخيره شده از cache خارج شده باشند مي بايست همواره قبل از دستيابي ، موجود بودن آنها در cache بررسي گردد .
• آيتم هاي موجود در cache از وابستگي ها ( dependencies ) حمايت مي نمايند . پياده كنندگان مي توانند يك شي cache شده را به يك فايل ، يك جدول بانك اطلاعاتي و يا يك منبع ديگر مرتبط نمايند . در صورت بروز تغييرات در منبع وابسته ، شي cache شده بطور اتوماتيك غيرمعتبر مي گردد و در نهايت از حافظه حذف مي شود .

اضافه كردن آيتم به cache

براي اضافه كردن يك شي درون cache از روش هاي مختلفي استفاده مي گردد . يكي از روش هاي موجود نسبت دهي داده مورد نظر به يك نام و ذخيره آن در شي cache است ( نظير كار با اشياء Session و Application ) . با توجه به اين كه در اين روش نمي توان براي شي cache شده يك مدت زمان خاص را مشخص نمود ، استفاده از اين روش كمتر توصيه شده است .

 

 Cache("KeyName") = objectToCache

يكي ديگر از روش هاي درج داده درون شي cache ، استفاده از متد Insert است . متد فوق داراي چهار نسخه خاص است . در جدول زير ، گرامر يكي از نسخه هاي فوق كه جزئيات بيش تري از كار را با بكارگيري پنچ پارامتر مشخص مي نمايد، نشان داده شده است .

Cache.Insert(key, item, dependencies, absoluteExpiration, slidingExpiration)

در جدول زير عملكرد هر يك از پارامترهاي متد Insert توضيح داده شده است .

پارامتر

عملكرد

Key

 نام در نظر گرفته شده براي آيتم Cacheشده را مشخص مي نمايد. بدين ترتيب ، امكان دستيابي به آيتم Cacheشده بر اساس نام فراهم  گردد.

Item

 شي واقعي كه قصد cachingآن را داريم ، مشخص مي نمايد .

dependencies

يك شي CacheDependencyكه به شما اجازه مي دهد يك وابستگي براي آيتم مورد نظر در cacheرا ايجاد نمائيد .
در صورتي كه قصد تعريف يك آيتم وابسته را نداريم ، مقدار اين پارامتر مي بايست  nullدر نظر گرفته شود .

absoluteExpiration

 يك شي DataTimeكه  زمان و تاريخ خارج كردن آيتم cacheشده  از cacheرا مشخص مي نمايد .

slidingExpiration

 يك شي TimeSpanكه مدت زمان انتظار بين درخواست هاي متوالي در صورت عدم استفاده از داده cacheشده جهت خروج از cacheرا مشخص مي نمايد .
به عنوان مثال ، در صورتي كه اين مقدار 20 دقيقه در نظر گرفته شود و در مدت زمان فوق هيچگونه درخواستي براي داده فوق دريافت نگردد ،‌ ASP.NETآن را از حافظه خارج خواهد كرد . 

جدول 1 : پارامترهاي متد Insert
معمولا" از تمامي پارامترهاي فوق در يك زمان استفاده نمي گردد . به عنوان مثال ، Cache dependencies يك ابزار خاص است كه به كمك آن مي توان وابستگي يك آيتم cache شده به ساير منابع تاثيرگذار را مشخص نمود .
در صورتي كه قصد استفاده از يك absolute expiration را داشته باشيم ، مي بايست مقدار پارامتر slidingExpiration معادل TimeSpan.Zero در نظر گرفته شود.

 Cache.Insert("MyItem", obj, Nothing,DateTime.Now.AddMinutes(60), TimeSpan.Zero)

در صورتي كه مطمئن باشيم اطلاعات موجود در يك آيتم cache شده در يك بازه زماني خاص معتبر باقي مي ماند ( نظير يك گزارش هواشناسي ) ، استفاده از absolute expiration توصيه مي گردد . در صورتي كه داده ذخيره شده در cache همواره معتبر باشد ( نظير كاتولوگ يك محصول ) ، استفاده از Sliding expiration توصيه مي گردد . به عنوان يك سياست مطلوب در خصوص بكارگيري Sliding expiration ، مي توان مقدار پارامتر absoluteExpiration را به DateTime.Max نسبت داد .

Cache.Insert("MyItem", obj, Nothing,DateTime.MaxValue, TimeSpan.FromMinutes(10))

يك مثال كاربردي

در برنامه زير يك سيستم caching داده ساده پياده سازي شده است . در اين مثال يك آيتم با نام TestItem كه تاريخ و زمان جاري را در خود نگهداري مي نمايد به مدت 30 ثانيه cache مي گردد . پس از postback صفحه ، در صورتي كه تاريخ اعتبار آيتم ذخيره شده در cache به اتمام نرسيده باشد ، مقدار آن از cache بازيابي و در خروجي نمايش داده مي شود . پس از اتمام تاريخ اعتبار آيتم ذخيره شده در cache ، مجددا" و بر اساس داده جديد ( تاريخ جديد سيستم ) آيتم مورد نظر ايجاد و جهت استفاده آتي در cache ذخيره مي گردد .

 

ذخيره و بازيابي داده در شي cache

<%@ Page Language="VB" Culture="fa-IR" UICulture="fa-IR" %>

<Script Runat="server">
   Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)   Handles Me.Load
    If Me.IsPostBack Then
      lblInfo.Text &= "ارسال مجددصفحه براي سرويس دهنده<br />"
    Else
      lblInfo.Text &= "ايجاد صفحه<br />"
   End If
  If Cache("TestItem") Is Nothing Then
    lblInfo.Text &= "ايجاد داده جهت ذخيره درcache<br />"
    Dim testItem As DateTime = DateTime.Now
    lblInfo.Text &= "به مدت 30 ثانيه<br />"
    Cache.Insert("TestItem", testItem, Nothing, DateTime.Now.AddSeconds(30), TimeSpan.Zero)
  Else
   lblInfo.Text &= "بازيابي داده ازcache...<br />"
   Dim testItem As DateTime = CType(Cache("TestItem"), DateTime)
   lblInfo.Text &= "دادهcache شده: '" & testItem.ToString()
   lblInfo.Text &= "'<br />"
 End If
 lblInfo.Text &= "<br />"

End Sub
</Script>

<html xmlns="http://www.w3.org/1999/xhtml" dir ="rtl">
 <head id="Head1" runat="server">
     <title>تستcaching داده</title>
 </head>
 <body style="font-family: Tahoma;">
    <form id="form1" runat="server">
      <div>
        <asp:Button ID="Button1" runat="server" Text="ارسالصفحه براي سرويس دهنده" Font-Names="Tahoma" />
        <br /><br />
        <asp:Label ID="lblInfo" runat="server"></asp:Label>
      </div>
   </form>
 </body>
</html>

در اين بخش براي آشنائي با نحوه عملكرد شي cache به بررسي يك نمونه مثال كاربردي پرداختيم كه در آن داده مورد نظر براي مدت زمان خاصي در cache مستقر مي گرديد . در ادامه و به منظور پاسخ به درخواست سرويس گيرندگان از داده ذخيره شده در cache مشروط به عدم اتمام تاريخ اعتبار آن استفاده مي گرديد . در صورت اتمام تاريخ مصرف نسخه cache شده ، داده جديد توليد و مجددا" در cache قرار مي گرفت . در اين مثال صرفا" يك داده ساده در cache قرار مي گرفت .
شايد براي شما اين سوال مطرح شده باشد كه آيا مي توان اطلاعات پيچيده تري نظير داده بازيابي شده از يك بانك اطلاعاتي را نيز بدين شكل در cache قرار داد تا بتوان از آن براي پاسخ به ساير سرويس گيرندگان استفاده نمود ؟ آيا مي توان يك سيستم فيلترينگ را بر اساس داده هاي cache شده پياده سازي نمود بگونه اي كه متناسب با خواسته كاربر بخشي از داده cache شده در اختيار وي قرار داده شود ؟ اجازه دهيد با بررسي يك مثال كاربردي به سوالات فوق پاسخ دهيم .
مثال : ايجاد caching با قابليت مشاهده چندين view از داده
در اين مثال اطلاعات مورد نظر از يك بانك اطلاعاتي ( به عنوان نمونه Northwind ) بازيابي و پس از ذخيره در يك DataSet در يك Gridview نمايش داده مي شود . DataSet در cache ذخيره مي گردد تا در آينده و قبل از اتمام تاريخ اعتبار آن بتوان از تمام و يا بخشي از اطلاعات آن متناسب با خواسته كاربر استفاده نمود .
خروجي صفحه وب بر اساس خواسته كاربر و به صورت پويا ايجاد مي گردد . در واقع ، كاربر است كه مشخص مي كند در خروجي قصد مشاهده چه نوع اطلاعاتي را دارد . خروجي برنامه فوق در چندين ستون مختلف مي تواند نمايش داده شود . كاربر با انتخاب يك و يا چندين ستون نظر خود را خصوص نحوه نمايش خروجي مشخص مي نمايد .

توضيحات برنامه :

• DataSet از طريق يك تابع اختصاصي و به صورت زير ايجاد مي گردد .

 

ايجاد DataSetبه كمك يك تابع اختصاصي

Function RetrieveData() As DataSet
  Dim connectionString As String = _
        WebConfigurationManager.ConnectionStrings("NORTHWNDConnectionString").ConnectionString
  Dim SQLSelect As String = "SELECT * FROM Customers"
  Dim con As New SqlConnection(connectionString)
  Dim cmd As New SqlCommand(SQLSelect, con)
  Dim adapter As New SqlDataAdapter(cmd)
  Dim ds As New DataSet()
  Try
    con.Open()
   adapter.Fill(ds, "Customers")
  Finally
    con.Close()
  End Try

Return ds
End Function

• در اولين مرتبه اي كه صفحه load مي گردد ، ليستي از ستون ها توسط يك كنترل CheckBoxList با نام chckColumns در خروجي و به منظور دريافت نقطه نظرات كاربر نمايش داده مي شود . بدين منظور از كد زير در روتين page_load استفاده شده است .

نمايش ليستي از ستون ها توسط يك كنترل CheckBoxList

chkColumns.DataSource = ds.Tables(0).Columns
chkColumns.DataMember = "Item"
chkColumns.DataBind()

• Dataset به مدت دو دقيقه كه توسط پارامتر sliding expiration مشخص شده است در cache قرار مي گيرد . ذخيره Dataset در Cache در زمان ايجاد DataSet و از طريق روتين GetDataSet و به كمك متد Insert شي cache انجام مي شود .

ذخيره DataSetدر cacheبه مدت 2 دقيقه

Cache.Insert("DataSet", ds, Nothing, DateTime.MaxValue,TimeSpan.FromMinutes(2))

• پس از كليك بر روي دكمه " فيلتر و نمايش اطلاعات " ، در ابتدا سعي مي گردد كه DataSet از طريق cache بازيابي گردد ( استفاده از روتين GetDataSet ) . در صورتي كه صفحه نتواند DataSet را از cache بازيابي نمايد ، تابع RetrieveData فراخوانده مي شود تا پس از توليد DataSet در ادامه بتوان آن را به cache اضافه نمود .
براي آگاهي كاربران منبع ارائه اطلاعات نيز در خروجي نمايش داده مي شود ( ايجاد و ذخيره اطلاعات در cache و يا بازيابي اطلاعات از cache ) .

بازيابي DataSetاز cacheو يا ايجاد و ذخيره مجدد DataSetدر cache

Function GetDataSet() As DataSet
   Dim dsPubs As DataSet
    If Cache("Titles") Is Nothing Then
      dsPubs = RetrieveData()
      Cache.Insert("Titles", dsPubs, Nothing, DateTime.MaxValue, TimeSpan.FromMinutes(2))
      lblCacheStatus.Text = "ايجاد اطلاعات و ذخيره آنها درcache"
   Else
     dsPubs = CType(Cache("Titles"), DataSet)
      lblCacheStatus.Text = "بازيابي اطلاعاتازcache"
  End If
  Return dsPubs
 End Function

• براي ارائه يك grid قابل پيكربندي ، كد موجود در روتين cmdApply_Click در DataTable حركت و تمامي ستون هائي را كه كاربر جهت عدم نمايش در خروجي فيلتر نموده است ، از grid حذف مي نمايد ( قبل از حذف ستون هائي از DataSet يك نسخه ثانويه از آن ايجاد مي گردد ) .
در اين رابطه شايد بتوان از گزينه هاي متعدد ديگري استفاده نمود ولي استراتژي بكار گرفته شده در مثال فوق بيانگر يك حقيقت مهم در خصوص caching است . زماني كه يك آيتم بازيابي مي گردد در واقع يك مرجع به شي cache شده بازيابي شده است و اگر شي تغيير يابد ، در حقيقت آيتم cache شده تغيير يافته است .

فيلترينگ داده بر اساس خواسته كاربر جهت نمايش در Gridview

Sub cmdApply_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdApply.Click
   Dim ds As DataSet = GetDataSet()
   ds = ds.Copy()
 
  For Each item As ListItem In chkColumns.Items
    If item.Selected Then
       ds.Tables(0).Columns.Remove(item.Text)
   End If
  Next
  gridPubs.DataSource = ds.Tables(0)
  gridPubs.DataBind()
End Sub

كد مثال فوق بطور كامل در جدول زير نشان داده شده است .

ذخيره داده بازيابي شده از بانك اطلاعاتي در cache
و استفاده از آن بر اساس خواسته كاربر قبل از اتمام تاريخ اعتبار آن

<%@ Page Language="VB" Culture="fa-IR" UICulture="fa-IR" %>
<%@ import Namespace="system.Data" %>
<%@ import Namespace="system.Data.SqlClient" %>
<%@ Import Namespace="System.Web.Configuration" %>

<script runat="server">

 Sub cmdApply_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdApply.Click
   Dim ds As DataSet = GetDataSet()
   ds = ds.Copy()
 
  For Each item As ListItem In chkColumns.Items
    If item.Selected Then
       ds.Tables(0).Columns.Remove(item.Text)
   End If
  Next
  gridPubs.DataSource = ds.Tables(0)
  gridPubs.DataBind()
End Sub

'=======================================================================
 Function GetDataSet() As DataSet
   Dim dsPubs As DataSet
    If Cache("Titles") Is Nothing Then
      dsPubs = RetrieveData()
      Cache.Insert("Titles", dsPubs, Nothing, DateTime.MaxValue, TimeSpan.FromMinutes(2))
      lblCacheStatus.Text = "ايجاد اطلاعات و ذخيره آنها درcache"
   Else
     dsPubs = CType(Cache("Titles"), DataSet)
      lblCacheStatus.Text = "بازيابي اطلاعاتازcache"
  End If
  Return dsPubs
 End Function

'=======================================================================
 Function RetrieveData() As DataSet
  Dim connectionString As String = _
        WebConfigurationManager.ConnectionStrings("NORTHWNDConnectionString").ConnectionString
  Dim SQLSelect As String = "SELECT * FROM Customers"
  Dim con As New SqlConnection(connectionString)
  Dim cmd As New SqlCommand(SQLSelect, con)
  Dim adapter As New SqlDataAdapter(cmd)
  Dim ds As New DataSet()
  Try
    con.Open()
   adapter.Fill(ds, "Customers")
  Finally
    con.Close()
  End Try

Return ds
End Function

'======================================================================
 Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Me.IsPostBack Then
  Cache.Remove("Titles")
  Dim dsPubs As DataSet = GetDataSet()
  chkColumns.DataSource = dsPubs.Tables(0).Columns
  chkColumns.DataMember = "Item"
  chkColumns.DataBind()
  End If
End Sub
</script>

'==============================================================
<html xmlns="http://www.w3.org/1999/xhtml" dir="rtl" >
  <head runat="server">
    <title>Untitled Page</title>
  </head>
  <body style="font-family: Tahoma">
   <form id="form1" runat="server">
    <div id="DIV1">
      <asp:label id="Label1" runat="server">ستون هائي راكه قصد نمايش آنها در خروجي را نداريد ، انتخاب نمائيد:
      </asp:label>
      <asp:checkboxlist id="chkColumns" runat="server" RepeatColumns="2"></asp:checkboxlist><br />
      <asp:button id="cmdApply" runat="server" Width="144px" Text="فيلتر و نمايشاطلاعات"
              Font-Names="Tahoma" ></asp:button><br />
      <asp:Label ID="lblCacheStatus" runat="server">Hide Columns:</asp:Label>
      <hr />
      <asp:gridview id="gridPubs" runat="server" Width="384px" Height="120px"
             BorderColor="#CC9966" BorderStyle="None" 
             BorderWidth="1px" BackColor="White" CellPadding="4"
            Font-Size="X-Small" Font-Names="Verdana" EnableViewState="False">
     <RowStyle ForeColor="#330099" BackColor="White" HorizontalAlign="Left"></RowStyle>
     <HeaderStyle Font-Bold="True" ForeColor="#FFFFCC" BackColor="#990000"></HeaderStyle>
    </asp:gridview>
   </div>
  </form>
 </body>
</html>

كنترل هاي ObjectDataSource ، SqlDataSource و XmlDataSource بطور ذاتي از امكانات caching حمايت مي نمايند . استفاده از caching به همراه كنترل هاي فوق اكيدا" توصيه مي گردد چراكه برخلاف كد سفارشي نوشته شده توسط پياده كنندگان به منظور دستيابي داده ، كنترل هاي منبع داده همواره در هر postback يك query را بر روي منبع داده اجراء مي نمايند .
كنترل هاي فوق ، همچنين براي هر كنترل نسبت دهي يك query در سطح منبع داده را اجراء مي نمايند . به عنوان نمونه اگر در يك صفحه از سه كنترل نسبت دهي داده در ارتباط با يك منبع داده يكسان استفاده شده باشد ، سه query مجزاء بر روي بانك اطلاعاتي و قبل از تفسير و ارسال صفحه براي سرويس گيرنده ، اجراء خواهد شد . بديهي است حتي با استفاده از امكانات اندك caching به همراه كنترل هاي منبع داده ، شاهد بهبود چشمگير كارآئي و كاهش load عملياتي در سمت سرويس دهنده خواهيم بود .
با اين كه تعداد زيادي از كنترل هاي منبع داده از caching حمايت مي نمايند ، ولي ويژگي فوق به عنوان يك ضرورت در بكارگيري كنترل هاي منبع داده مطرح نمي گردد و مي توان از كنترل هاي منبع داده ئي كه از پتانسيل caching حمايت نمي نمايند نيز استفاده كرد .
براي حمايت از caching كنترل هاي ObjectDataSource ، SqlDataSource و XmlDataSource از خصلت هاي مشابهي استفاده مي نمايند . در جدول 1 ، خصلت هاي فوق نشان داده شده اند .

خصلت

عملكرد

 EnableCaching

 با نسبت دهي مقدار Trueبه خصلت فوق ، پتانسيل cachingفعال مي گردد . مقدار پيش فرض خصلت فوق Falseدر نظر گرفته مي شود . 

CacheExpirationPolicy

 سياست و يا استراتژي زمان اتمام تاريخ اعتبار cacheرا مشخص مي نمايد . بر اين اساس مي توان مقدار خصلت فوق را ثابت و يا متغير ( مدت زمان بين دو درخواست متوالي ) در نظر گرفت . 

 CacheDuration

 مدت زمان cachingآيتم مورد نظر در cacheرا بر حسب ثانيه  مشخص مي نمايد .


CacheKeyDependency
و
SqlCacheDependency

 امكان ايجاد يك وابستگي بين يك آيتم cacheشده با آيتم ديگر در data cache  ( با استفاده از CacheKeyDependency) و يا يك جدول بانك اطلاعاتي(با استفاده از SqlCacheDependency) را فراهم مي نمايد .  

جدول 1 : خصلت هاي caching كنترل هاي منبع داده
Add Comments
Name:
Email:  
User Comments:
SecurityCode: Captcha ImageChange Image