سؤال

مؤخرا, بينما كان يعمل على بعض التعليمات البرمجية ل ASP.NET المشروع في العمل.نحن في حاجة إلى تتبع util أن تأخذ الأساسية المقاييس على نشاط المستخدم (صفحة ضرب العد الخ) ونحن سوف تتبع لهم في Session, ثم حفظ البيانات DB عبر Session_End في Global.asax.

بدأت القرصنة بعيدا ، رمز الأولي عملت بشكل جيد, تحديث ديسيبل على كل تحميل الصفحة.أردت أن إزالة هذا DB ضرب على كل طلب على الرغم من الاعتماد فقط على Session_End لتخزين جميع البيانات.

كل من تتبع رمز مغلف في Tracker فئة ، بما في ذلك الخصائص أساسا التفاف متغيرات جلسة العمل.

المشكلة هو أنني عندما أعدم Tracker.Log() في Session_End الأسلوب ، HttpContext.Current.Session في تعقب رمز كانت فاشلة مع NullReferenceException.الآن, وهذا أمر منطقي لأن HttpContext يتعلق دائما الحالي طلب, و بالطبع في Session_End, لا يوجد الطلب.

وأنا أعلم أن Global.asax لديه Session المنشأة والتي ترجع HttpSessionState في الواقع يبدو أن تعمل بشكل جيد (انتهى عن طريق الحقن في تعقب)..

ولكن أنا الغريب كيف يمكنني الحصول على نفس إشارة إلى HttpSessionState كائن يستخدم من قبل Global.asax من خارج من Global.asax?

شكرا مقدما يا شباب أقدر الإدخال.:)

هل كانت مفيدة؟

المحلول

العالمية.asax تنفذ HttpApplication - وهو ما كنت تتحدث إلى عند استدعاء هذا من داخلها.

على وثائق MSDN HttpApplication وقد التفاصيل حول كيف يمكنك الحصول على عقد من ذلك في HttpHandler على سبيل المثال ، ومن ثم الوصول إلى خصائص مختلفة على ذلك.

ومع ذلك

التطبيق الخاص بك يمكن إنشاء مثيلات متعددة من HttpApplication للتعامل مع طلبات موازية و هذه الحالات يمكن إعادة استخدامها ، حتى مجرد التقاط ذلك بطريقة أو بأخرى لن أضمن أن يكون لديك حق واحد.

أنا أيضا إضافة ملاحظة من الحذر - إذا تعطل التطبيق ، لا أضمن أن session_end سيكون اتصل عليك فقدت كل البيانات عبر جميع الدورات واضح لا شيء جيد.

أوافق على أن تسجيل الدخول على كل صفحة ربما لا يكون فكرة عظيمة, ولكن ربما في منتصف الطريق من البيت مع بعض غير متزامن تسجيل يحدث - كنت اطلاق النار تفاصيل قبالة إلى تسجيل الدرجة أن كل الآن وبعد ذلك سجلات تفاصيل أنت بعد لا تزال غير 100% الصلبة إذا تعطل التطبيق ، ولكن أنت أقل من المحتمل أن تفقد كل شيء.

نصائح أخرى

للإجابة على السؤال الأصلي أفضل:

الخلفية

كل صفحة طلب يدور جديد Session كائن ثم يضخم من الدورة المخزن.للقيام بذلك, فإنه يستخدم ملف تعريف الارتباط المقدمة من قبل العميل أو مسار خاص بناء (على بدون ملفات تعريف ارتباط جلسة).مع هذه الدورة معرف ، يتشاور الدورة متجر deserializes (هذا هو السبب في كل مقدمي ولكن InProc تحتاج إلى أن تكون للتسلسل) الدورة الجديدة الكائن.

في حالة InProc مزود مجرد أيدي الإشارة المخزنة في HttpCache مرتبطا من قبل معرف جلسة. هذا هو السبب في InProc مزود قطرات حالة جلسة العمل عند AppDomain يتم إعادة تدويرها (و أيضا لماذا عدة ملقمات ويب لا يمكن مشاركة حالة جلسة العمل InProc.

هذا تم إنشاؤه حديثا تضخم جسم عالق في Context.Items جمع بحيث انها متوفرة طوال مدة الطلب.

أي تغييرات تجريها على Session كائن ثم استمرت في نهاية الطلب إلى الدورة مخزن التسلسلية (أو حالة InProc ، HttpCache تحديث الإدخال).

منذ Session_End الحرائق دون الطلب الحالي في الطيران ، Session الكائن هو نسج سابق نيلو مع أي معلومات متاحة.في حالة استخدام حالة جلسة العمل InProc, انتهاء HttpCache يتسبب في رد هذا الحدث في Session_End الحدث, حتى الدورة الدخول متاح, ولكن لا يزال نسخة من آخر ما تم تخزينها في HttpContext.Cache.يتم تخزين هذه القيمة ضد HttpApplication.Session عن طريقة الداخلي (يسمى ProcessSpecialRequest) حيث أنها متاحة في ذلك الوقت.تحت كل الحالات الأخرى ، داخليا يأتي من HttpContext.Current.Session القيمة.

الجواب

منذ Session_End دائما حرائق ضد null السياق ، يجب عليك دائما استخدام هذا.الدورة في هذا الحدث وتمرير HttpSessionState كائن إلى تتبع التعليمات البرمجية.في جميع السياقات الأخرى ، أنه على ما يرام تماما لجلب من HttpContext.Current.Session ثم تنتقل إلى رمز التعقب. لا, ومع ذلك اسمحوا رمز التعقب تصل الدورة السياق.

جوابي

لا تستخدم Session_End إلا إذا كنت تعرف أن الدورة مخزن لديك يدعم Session_End, التي لا اذا عاد true من SetItemExpireCallback.فقط في مربع مخزن الذي يفعل هو InProcSessionState متجر.فمن الممكن أن يكتب الدورة المخزن الذي لا ولكن السؤال من الذي سوف عملية Session_End هو نوع من غامضا إذا كان هناك عدة ملقمات.

أعتقد أنك أجبت على السؤال الخاص بك:عادة الدورة الملكية في العالم.asax و HttpContext.الحالي.الدورة هي نفسها (إذا كان هناك طلب).ولكن في حالة الدورة مهلة لا يوجد طلب نشط وبالتالي لا يمكنك استخدام HttpContext.الحالي.

إذا كنت ترغب في الوصول إلى الدورة من طريقة تسمى من قبل Session_End ، ثم تمر عليه كمعلمة.إنشاء طاقتها إصدار السجل() الأسلوب الذي يأخذ HttpSessionState كمعلمة ، ثم تعقب المكالمات.سجل(هذا.الدورة) من Session_End معالج الحدث.

راجع للشغل:أنت تدرك أنه لا يمكن الاعتماد على الدورة نهاية الحدث في أي حال من الأحوال ؟ وسوف تعمل فقط طالما لديك حالة جلسة العمل في العملية.عند استخدام SQL server أو StateServer الجرب الدورة الدولة, الدورة نهاية الحدث لا النار.

على Session_End الحدث أثار فقط عندما sessionstate mode يتم تعيين InProc في Web.config الملف.إذا وضع الدورة هو StateServer أو SQLServer, الحدث ليس المطروحة.

استخدام Session["SessionItemKey"] للحصول على الدورة القيمة.

حسنا أنا في نفس المشكلة تتبع دورة النشاط.بدلا من استخدام session_end الحدث ، لقد نفذت واجهة IDisposable والمدمر إلى sessiontracker الدرجة.لقد تعديل Dispose() طريقة لحفظ دورة النشاط ديسيبل.أنا استدعاء الأسلوب الكائنات.Dispose() عندما يقوم المستخدم بالنقر على زر الخروج.إذا كان المستخدم إغلاق المتصفح عن طريق الخطأ ، ثم GC سوف نداء المدمر أثناء تنظيف الكائنات (ليس على الفور ولكن بالتأكيد فإنه سيتم استدعاء هذا الأسلوب بعد وقت ما).المدمر طريقة داخليا تنفيذ نفس التصرف() طريقة لحفظ الدورة في ديسيبل.

-شان

الدورة متاحة في العالمية.asax خلال Session_Start الحدث.ربما تنتظر حتى هذه النقطة أن تفعل الأشياء ؟

تذكر أن Session_End يعمل عند بدء الدورة مرات دون نشاط.المتصفح لا تنشأ ذلك الحدث (لأنه غير نشط) ، حتى المرة الوحيدة التي كنت في الواقع الحصول على الحدث عند استخدام InProc مزود.في كل موفر هذا الحدث لن النار.

أخلاقيا ؟ لا تستخدم Session_End.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top