سؤال

وهناك هذا الكائن DB-اتصال من هذا القبيل سوف تحتاج تطبيق الويب الخاص بي. أنها بطيئة جدا لخلق وسوف تستخدم نادرا، لذلك أود أن تبقي مثيل واحد فقط من حولها. إذا عدة طلبات في حاجة إليها في الوقت نفسه، وسوف lock() الكائن وتسلسل وصولها.

لجعل الامور أكثر متعة الكائن هو IDisposable ويمكن أن تكون مغلقة. وبطبيعة الحال، سوف تجنب كتابة التعليمات البرمجية أن يغلق، ولكن ... كما تعلمون ... أفضل آمنة من آسف، أليس كذلك؟

وهكذا، فإن النهج الساذج سيكون لتنفيذها شيء من هذا القبيل:

private static DBClass _Instance;
private static object _DBLock = new object();

public DBClass GetDB()
{
    if ( _Instance == null )
        lock (_DBLock )
            if ( _Instance == null )
                _Instance = CreateInstance();
    lock (_Instance)
        if ( _Instance.Disposed )
            _Instance = CreateInstance();
    return _Instance;
}

وبعد ذلك سوف يتم استخدامه مثل:

lock (var Conn = Global.GetDB() )
{
    // Use Conn here.
}

وهذا من المحتمل أن تعمل أكثر من مرة، ولكن أرى فرصة يمكن استغلالها - إذا كان اثنان المواضيع دعوة هذا في الوقت نفسه، ويحصلون على نفس مثيل في نفس الوقت، ومن ثم يمكن للمرء أن لا يزال Dispose() من قبل الآخر يكتسب lock() على ذلك. وهكذا - فشل متاحة في وقت لاحق. التحقق من Disposed في كل مكان يستخدم على ما يبدو أيضا حرج. في الواقع، lock()ing يبدو محرجا للغاية، ولكن المقام ليس في حد ذاته موضوع آمنة حتى لا يكون هناك شيء يمكنني القيام به حيال ذلك.

وكيف يمكن تطبيق هذا؟

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

المحلول

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

وبالنظر إلى أن كنت لا تريد في الواقع التخلص من الكائن، ليس هناك أي سبب لعدم التفاف عليه في شيء أن تطبق نفس API من دون تعريض التخلص لكن؟ وبهذه الطريقة يمكن أيضا تغليف قفل، وربما، وهذا يتوقف على الطريقة التي فعلا استخدام الكائن. وهناك طريقة أخرى للقيام بذلك يكون إلى فضح API من حيث Action<DBClass> - الذي يمر في الإجراء الذي تريد أن تأخذ مع الكائن، والمساعد يعتني خلق المثيل وقفل بشكل مناسب

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

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