c# - لماذا يجب أن يكون كائن القفل ثابتًا؟




multithreading locking (2)

لا يجب أن تكون ثابتة ، في بعض الأحيان لا ينبغي أن تكون ثابتة.

يجب أن يكون المتغير في نفس نطاق الطرق التي تستخدمها من أجل القفل. إذا كانت الطرق ثابتة ، فيجب أن يكون المتغير ثابتًا ، وإذا كانت الطرق هي طرائق مثيل ، فيجب أن يكون المتغيّر متغيرًا.

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

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

لكن لماذا ثابت؟

private static readonly object Locker = new object();

في النهاية ، يُستخدم الحقل داخل فئتي فقط ، ويمكنني أيضًا استخدام ذلك فقط بدلاً من ذلك:

private readonly object Locker = new object();

أي تعليقات؟

تحديث:

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

private readonly object Locker = new object();

وهنا الرمز:

    private int _priceA;
    private int _priceB;
    private EventWaitHandle[] _waithandle;
    private readonly IService _service;

//ctor
public ModuleAViewModel(IService service)
    {
        _service = service;
        _modelA = new ModelA();
        _waithandle = new ManualResetEvent[2];
        _waithandle[0] = new ManualResetEvent(false);
        _waithandle[1] = new ManualResetEvent(false);
        LoadDataByThread();
    }


 private void LoadDataByThread()
        {
            new Thread(() =>
                           {
                               new Thread(() =>
                               {
                                   lock (Locker)
                                   {
                                       _priceA = _service.GetPriceA();
                                   }
                                   _waithandle[0].Set();
                               }).Start();

                               new Thread(() =>
                               {
                                   lock (Locker)
                                   {
                                       _priceB = _service.GetPriceB();
                                   }
                                   _waithandle[1].Set();
                               }).Start();

                               WaitHandle.WaitAll(_waithandle);
                               PriceA = _priceA;
                               PriceB = _priceB;
                           }).Start();
        }

شكر


ليس من الشائع استخدام كائن للقراءة فقط ثابت خاص للتثبيت في مؤشر الترابط المتعدد - بدلاً من ذلك ، من الشائع استخدام القفل في الدقة المناسبة / المختارة . في بعض الأحيان هذا هو static . في كثير من الأحيان ، المنظمة البحرية الدولية ، لم يكن - ولكن على سبيل المثال .

المرة الرئيسية التي ترى فيها قفلًا static هي ذاكرة تخزين مؤقت عالمية ، أو تحميل مؤجل للبيانات / المفردات العالمية. وفي الأخير ، هناك طرق أفضل للقيام بذلك على أي حال .

لذلك يعتمد الأمر فعلاً: كيف تستخدم Locker في السيناريو الخاص بك؟ هل تحمي شيئًا ثابتًا في حد ذاته ؟ إذا كان الأمر كذلك ، يجب أن يكون القفل ثابتًا. إذا كان يقوم بحماية شيء يستند إلى مثيل ، فإن IMO يجب أن يكون القفل أيضًا مستندًا إلى المثيل.







locking