State Management در ASP. NET 2.0 (بخش دوازدهم)
آنچه تاكنون گفته شده است :
بخش اول |
مفاهيم اوليه |
: |
ضرورت مديريت state در برنامه هاي وب |
بخش دوم |
view state |
: |
نحوه ايمن سازي اطلاعات ذخيره شده در view state |
بخش سوم |
view state |
: |
نحوه نگهداري Member Variables و اشياء سفارشي |
بخش چهارم |
cross-page posting |
: |
انتقال اطلاعات از يك صفحه به صفحه اي ديگر |
بخش پنجم |
cross-page posting |
: |
نحوه دريافت اطلاعات از صفحه مبداء |
بخش ششم |
Query String |
: |
نحوه انتقال اطلاعات بين صفحات |
بخش هفتم |
كوكي هاي سفارشي |
: |
نحوه عملكرد كوكي هاي سفارشي |
بخش هشتم |
Session State |
: |
مفاهيم و معماري session |
بخش نهم |
Session State |
: |
نحوه استفاده از session state |
بخش دهم |
Session State |
: |
پيكربندي session در برنامه هاي وب |
بخش يازدهم |
Session State |
: |
پيكربندي session در برنامه هاي وب |
در اين بخش با application state آشنا مي شويم .
با استفاده از application state مي توان اشياء سراسري ( global ) را با هدف دستيابي توسط هر يك از سرويس گيرندگان ذخيره كرد . عملكرد application state بر اساس كلاس System.Web.HttpApplicationState مي باشد كه بطور پيش فرض از طريق شي از قبل تعبيه شده Application در تمامي صفحات قابل استفاده است .
طرز كار application state مشابه session state است و از اشيائي با نوع هاي مشابه ، نگهداري اطلاعات در سمت سرويس دهنده و گرامر مبتني بر ديكشنري استفاده مي نمايد . استفاده از يك شمارنده سراسري به منظور نگهداري تعداد دفعاتي كه يك عمليات خاص توسط تمامي سرويس گيرندگان يك برنامه وب انجام مي شود ، يك نمونه متداول استفاده از application state مي باشد .
مثلا" مي توان يك event handler در فايل global.asax را تعريف كرد تا تعداد session ايجاد شده و يا تعداد درخواست هاي دريافتي توسط يك برنامه را ثبت كند . همچنين ، مي توان از روشي مشابه در Page. Load به منظور تعيين تعداد دفعاتي كه يك صفحه خاص توسط سرويس گيرندگان مختلف درخواست شده است ، استفاده كرد .
كد زير نحوه انجام اين كار را مشخص مي كند .
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load Dim Count As Integer = CType(Application("HitCounter"), Integer) Count += 1 Application("HitCounter") = Count lblCounter.Text = Count.ToString() End Sub |
لازم است مجددا" به اين نكته اشاره گردد كه آيتم هاي application state به عنوان شي ذخيره مي گردند ، بنابراين مي بايست در زمان بازيابي آنها را cast كرد . تاريخ اعتبار و يا مصرف آيتم هاي ذخيره شده در application state هرگز به اتمام نخواهد رسيد و تا زماني كه برنامه و يا سرويس دهنده راه اندازي مجدد نگردد و يا حوزه برنامه خود را refresh ننمايد ( به علت تنظيمات ادواري اتوماتيك پردازه و يا بهنگام سازي يكي از صفحات و يا عناصر موجود در برنامه ) ، امكان استفاده از آنها وجود خواهد داشت .
امروزه اغلب از application state به دليل عدم كارآئي مناسب استفاده نمي شود . در مثال قبل ، همواره اين احتمال وجود خواهد داشت كه در شمارنده مقدار درستي ذخيره نگردد ( خصوصا" در مواردي كه ترافيك بالا باشد ) . به عنوان مثال ، در صورتي كه دو سرويس گيرنده در يك زمان مشابه صفحه اي را درخواست نمايند ، داراي مجموعه اي از رويدادها به شرح ذيل خواهيم بود :
- كاربر A مقدار جاري شمارنده را ( فرضا" عدد 432 ) بازيابي مي نمايد .
- كاربر B مقدار جاري شمارنده را ( فرضا" عدد 432 ) بازيابي مي نمايد .
- كاربر A مقدار شمارنده را تغيير و آن را به 433 تغيير مي دهد .
- كاربر B مقدار شمارنده را تغيير و آن را به 433 تغيير مي دهد .
به عبارت ديگر ، يكي از درخواست ها باعث افزايش شمارنده نمي گردد ، چراكه دو سرويس گيرنده بطور همزمان به شمارنده دستيابي داشته اند . براي پيشگيري از بروز اين مسئله ، مي بايست از متدهاي Lock و Unlock استفاده كرد . با استفاده از متدهاي فوق در هر لحظه صرفا" به يك سرويس گيرنده اجازه دستيابي به مجموعه application state داده مي شود .
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load Application.Lock() Dim Count As Integer = CType(Application("HitCounter"), Integer) Count += 1 Application("HitCounter") = Count Application.Unlock() lblCounter.Text = Count.ToString() End Sub |
ساير سرويس گيرندگاني كه صفحه را درخواست مي نمايند مي بايست تا زماني كه مجموعه application state آزاد نشده است ، منتظر بمانند . اين وضعيت مي تواند كاهش كارآئي برنامه را به دنبال داشته باشد .
به عنوان يك قانون كلي ، مقاديري كه دائما" و با فركانس بالا تغيير مي يابند نمي توانند كانديدي مناسب جهت استفاده از application state باشند .
application state در دنياي دات نت بندرت استفاده مي شود چراكه دو كاربرد متداول استفاده از آن با روش هاي موثرتر ديگر جايگزين شده است .
-
در گذشته ، از application state براي ذخيره ثوابت در سطح برنامه نظير يك connection string بانك اطلاعاتي استفاده مي گرديد . هم اينك در دات نت مي توان اين نوع ثوابت را به سادگي در فايل web.config كه به مراتب از انعطاف بيشتري برخوردار است ذخيره نمود .
-
در گذشته براي ذخيره اطلاعاتي كه در يك برنامه از آنها بدفعات استفاده مي گرديد و براي توليد اين اطلاعات زمان زيادي صرف مي گرديد ، استفاده مي شد ( نظير يك كاتولوگ كامل از محصولات ) . افزايش حجم كاتالوگ و معتبر سازي داده موجود در اينچنين كاتالوگ هائي ، همواره از مشكلات برنامه نويسان بوده است . هم اينك و با استفاده از دات نت مي توان از فنآوري cache كه داراي كارآئي بمراتب بالاتري نسبت به روش هاي پيشين و بكارگرفته شده در application state است ، استفاده كرد .
فايل Global.asax
با استفاده از فايل global.asax مي توان كد مورد نياز جهت برخورد با رويدادهائي در سطح برنامه را ايجاد كرد . رويدادهاي فوق در نقاط مختلفي از چرخه حيات يك برنامه وب محقق مي گردند ( مثلا" زماني كه session ايجاد مي گردد ) . همين موضوع باعث شده است كه فايل global.asax بتواند در تعامل مناسب با ويژگي هاي state management قرار بگيرد . مثلا" مي توان از فايل global.asax براي مقداردهي اوليه مجموعه اي از اشياء كه قصد داريم آنها را در application state ذخيره نمائيم ، استفاده كرد .
فايل global.asax ، همانند يك فايل aspx . است . با اين تفاوت كه اين نوع فايل ها نمي توانند شامل تگ هاي HTML و يا ASP. NET باشند . در مقابل مي توان در آنها event handler مورد نياز را قرار داد . مثلا" فايل global.asax زير در مقابل رويداد Application.EndRequest از خود واكنش نشان مي دهد ( رويدادي كه قبل از ارسال صفحه براي كاربر محقق مي گردد ) .
<%@ Application Language="VB" %> <script runat="server"> Sub Application_EndRequest(ByVal sender As Object, ByVal e As EventArgs) Response.Write("<hr>This page was served at " & DateTime.Now.ToString()) End Sub </script> |
event handler فوق از متد write شي از قبل تعبيه شده Response براي نوشتن يك footer در پائين صفحه ( تاريخ و زمان ايجاد صفحه ) استفاده مي نمايد .
هر برنامه ASP.NET مي تواند داراي يك فايل global.asax باشد كه پس از استقرار در دايركتوري مجازي مربوطه ، ASP.NET آن را بطور اتوماتيك تشخيص و از آن استفاده خواهد كرد . مثلا" ، اگر فايل global.asax فوق را در يك دايركتوري مجازي قرار دهيم ، شاهد نمايش يك footer در پائين هر يك از صفحات موجود در برنامه خواهيم بود .
اضافه كردن يك footer اتوماتيك در پائين صفحات ، يك عمليات مفيد براي سايت هاي حرفه اي نمي باشد . نوشتن يك ركورد در يك بانك اطلاعاتي مختص ثبت وقايع ( log ) ، شايد كاربرد مناسب تري از ويژگي فوق را نشان دهد . هم اينك تعداد زيادي از برنامه نويسان برنامه هاي وب تمايل به استفاده از فايل global.asax را ندارند . فايل فوق از مدل code-behind حمايت مي نمايد .
رويدادهاي Application
Application.EndRequest ، صرفا" يكي از رويدادهاي موجود جهت استفاده در فايل global.asax است . براي ايجاد يك event handler متفاوت ، مي توان يك روتين با نام دلخواه را ايجاد كرد .
برخي از متداولترين رويدادهاي application عبارتند از :
-
Application_Start : در زمان آغاز به كار برنامه و دريافت اولين درخواست توسط هر يك از كاربران ، محقق مي گردد . رويداد فوق در پاسخ به درخواست هاي بعدي محقق نخواهد شد . از اين رويداد معمولا" براي ايجاد و يا cache برخي اطلاعات اوليه استفاده مي شود.
-
Application_End : رويداد فوق پس از اتمام فعاليت برنامه ، محقق مي گردد ( عمدتا" زماني كه سرويس دهنده وب راه اندازي مجدد مي گردد ) . در روتين مربوطه مي توان كد مورد نياز براي پاكسازي را درج كرد .
-
Application_BeginRequest : رويداد فوق پس از دريافت هر درخواست توسط برنامه ، محقق مي گردد ( قبل از اجراي كد صفحه ) .
-
Application_EndRequest : رويداد فوق پس از دريافت هر درخواست توسط برنامه ، محقق مي گردد ( پس از اجراي كد صفحه ) .
-
Session_Start : رويداد فوق زماني محقق مي گردد كه درخواست يك كاربر جديد دريافت و يك session فعاليت خود را آغاز نمايد .
-
Session_End : رويداد فوق زماني محقق مي گردد كه مدت زمان حيات يك session به اتمام رسيده باشد ( از طريق كد و يا بطور اتوماتيك ) .
-
Application_Error : رويداد فوق در پاسخ به يك خطاء غيرقابل پيش بيني، محقق مي گردد .
در بخش پاياني به جمع بندي دوازده مقاله منتشر شده در خصوص session state خواهيم پرداخت .
برگرفته از سايت سخا روش