سؤال

لدي تطبيق ويب يستخدم حاليًا HttpContext الحالي لتخزين سياق بيانات LINQ.يستمر السياق للطلب الحالي، على أساس كل مستخدم، لكل مدونة ريك ستراهل:

string ocKey = "ocm_" + HttpContext.Current.GetHashCode().ToString("x")  
Thread.CurrentContext.ContextID.ToString();

if (!HttpContext.Current.Items.Contains(ocKey))
{
    // Get new Data Context and store it in the HTTP Context
}

ومع ذلك، لدي بعض البرامج النصية التي يتم تنفيذها من ملف global.asax، ذلك لا تملك سياق المتشعب. HttpContext.Current فارغ, لأن الخادم هو الذي يقدم "الطلب".

هل هناك كائن مكافئ يمكنني استخدامه لتخزين سياق البيانات؟لذلك لا داعي للقلق بشأن إعادة إنشائه وإرفاق/فصل الكائنات؟أريد فقط الحفاظ على السياق طوال عمر عملياتي.

محدث:

أحاول حاليًا استخدام متغير ثابت في فئة مساعد DAL الخاصة بي.عند الاستدعاء الأول لأحد الأساليب الموجودة في الفصل، يتم إنشاء مثيل DataContext وتخزينه في المتغير الثابت.في نهاية العملية، أقوم باستدعاء طريقة أخرى تستدعي Dispose on the DataContext، وتقوم بتعيين المتغير الثابت على NULL.

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

المحلول

ألا يمكنك فقط استخدام متغير ثابت خصيصًا لتلك البرامج النصية؟سيكون لها نفس مدة الحياة مثل AppDomain.ربما ينبغي عليك التفكير مليًا في أي مخاوف تتعلق بالتزامن، ولكن يبدو أن ذلك هو أبسط طريقة للحفاظ على القيمة.

(لقد قمت للتو بالتحقق، وعلى الرغم من وجود مثيل واحد لـ HttpApplication يمكن استخدامها لخدمة طلبات متعددة، كل منها يخدم طلبًا واحدًا فقط في كل مرة - مما يشير إلى أنه يتم إنشاء مثيلات متعددة لمعالجة الطلب المتزامن.لم أتحقق من صحة ذلك، ولكن يبدو أنه لن يكون من الآمن الاحتفاظ به في متغير مثيل.)

يحرر:تشير إجابة جوش إلى أنك تريد أن يكون هذا لكل موضوع.يبدو هذا غريبًا بعض الشيء بالنسبة لي، إلا إذا كان لديك كثير من بين هذه الأحداث التي تحدث، من المحتمل جدًا أن تراها يتم تنفيذها فقط على سلاسل محادثات مختلفة، مما يجعل عملية المشاركة بأكملها عديمة الجدوى.إذا كنت تريد حقًا هذا النوع من الأشياء، فأنا أقترح فقط استخدام متغير مثيل في ملف HttpApplication-فئة مشتقة - للسبب الموضح في الفقرة أعلاه بالضبط :)

نصائح أخرى

لماذا لا تستخدم HttpContext الحالي؟البرامج النصية الموجودة في ملف global.asax الخاص بك كلها نتيجة لطلب قادم إلى الخادم، لذلك يجب أن يكون هناك سياق مرتبط بهذا الطلب يمكنك الحصول عليه.

لا أفهم الحاجة إلى إنشاء المفتاح بناءً على رمز التجزئة أو مؤشر الترابط.سيكون هناك مثيل منفصل لـ HttpContext لكل طلب يأتي، وسيكون هذا المثيل خاصًا بسلسلة الرسائل التي تعالج الطلب.ولهذا السبب، يكون المفتاح عديم القيمة إلى حد كبير عندما يعتمد على مثيل HttpContext والخيط.

وأيضًا، كيف تتخلص من DataContext عند الانتهاء؟إنه ينفذ IDisposable لسبب ما، لذلك أوصي بعدم استخدام مثيل مشترك مثل هذا.


تحديث

يشير في التعليقات إلى وجود مؤقت قيد التشغيل يقوم بتنفيذ البرامج النصية.بدلاً من المؤقت، أوصي بإعداد مهمة مجدولة والتي ستستدعي خدمة ويب أو صفحة محددة مسبقًا على الموقع والتي ستقوم بتنفيذ المهمة.ثم سيكون لديك دائمًا HttpContext للعمل معه.

HttpContext.Current هي طريقة ثابتة ويجب أن تكون متاحة من أي مكان طالما يتم تنفيذ التعليمات البرمجية في سياق الطلب.

في حالتك التي لا يتم تنفيذها في سياق الطلب، يمكنك النظر في استخدام Application.Cache ولكني أود أن أحذر من إبقاء DataContext مفتوحًا.أنا لست على دراية كبيرة بالربط بالكيانات، لذا قد أكون مخطئًا، لكن التخزين المؤقت للعناصر ذات الصلة بقاعدة البيانات مثل الاتصالات أمر سيء بشكل عام.

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

يحرر

كما يشير JS، يمكنك استخدام متغير ثابت.يمكنك أيضًا تحديد متغير مثيل تم وضع علامة عليه بسمة ThreadLocal.سيعطي هذا كل مؤشر ترابط نسخته الخاصة من المتغير، ويمكن أن يزيل التنافس.نظرًا لأنك تريد أن يكون لكل موضوع نسخته الخاصة على أي حال.

هل هناك سبب لضرورة التعامل معها بنفس طريقة التعامل مع DataContexts الأخرى؟يبدو لي أنه إذا كان السياق مطلوبًا فقط داخل روتين التعامل مع الحدث، فلن تحتاج إلى الاحتفاظ به.خاصة إذا كان في Application_Start (حسب تعليقك)، فلن أزعج تخزينه مؤقتًا في أي مكان - فقط استخدمه محليًا وقم بتمريره إلى الطرق الأخرى حسب الحاجة.

قم بتعيين DataContext كمعلمة الحالة عند إنشاء المؤقت.بناءً على المعلومات التي نشرتها في التعليقات، يبدو لي أن DataContext الخاص بك مرتبط بالمؤقتات أكثر من أي شيء آخر.

تجنب أيضًا استخدام نفس DataContext لأجهزة ضبط الوقت المختلفة، لأنه سينتهي بك الأمر بتعديلات مختلطة من أجهزة ضبط الوقت المختلفة.تأكد أيضًا من عدم تشغيل منطق المؤقت نفسه مرتين، لأنه قد يتسبب في نفس الأمر، على سبيل المثال.فترة قصيرة جدًا بدون سيطرة.

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