سؤال

ولدي ملف للقراءة والكتابة إليه. ولست بحاجة للتأكد لها عندما كتب ل، لا أحد آخر يحاول الكتابة إليه.

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

public static TYPE Property{

get{
    data mydata;
    Object obj = new object();
    Monitor.Enter(obj);

    // check if data has not changed
    // if it has not, just read

    using (Stream stream = File.Open(fileLocation, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
        //....
    }
    // else, if data changed, then need to write to  file to save the new data

    using (Stream stream = File.Open(fileLocation, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read)) {
        BinaryFormatter bf = new BinaryFormatter();

        try {
            bf.Serialize(stream, (data);
        }
        //DONE processing

        Monitor.Pulse(obj);
        Monitor.Exit(obj);
        return data
}
هل كانت مفيدة؟

المحلول

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

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

وعلى سبيل المثال:

private static readonly object monitor = new object();

public static TYPE Property
{
    get
    {
        lock(monitor)
        {
            // check if data has not changed
            // if it has not, just read
            using (Stream stream = File.Open(fileLocation, 
                   FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                ....
            }
            // else, if data changed, then need to write to 
            // file to save the new data
            using (Stream stream = File.Open
                       (fileLocation, FileMode.OpenOrCreate,
                        FileAccess.ReadWrite, FileShare.Read))
            {
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(stream, data);
            }
            return data;
        }
    }
}

وبوصفها جانبا، وهذا يبدو وكأنه القيام بالمزيد من العمل مما كنت أتوقع حقا في الممتلكات. هل أنت متأكد من طريقة لن يكون أكثر منطقية؟

نصائح أخرى

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

وبعبارة أخرى لا يوجد تأمين.

وكملاحظة جانبية - لماذا لا تستخدم بيان قفل؟ سوف لا تزال بحاجة إلى وجوه قفل العالمي.

والسبب في المتغير العالمي مقابل المتغير المحلي الخاص بك هو أن LOCK يتم تأمين الواقع أسفل نقطة مرجعية في memeory كما أفهمها. في كل مرة كنت مثيل كائن جديد، أي "كائن الكائنات = كائن جديد ()؛"، وأنت خلق كائن جديد، مع أنه نفسه مؤشر فريد من نوعه في الذاكرة. لذلك عندما ينظر LOCK لمعرفة ما إذا تم تأمين نقطة في الذاكرة إلى أسفل، فإنه ليس كذلك. لانها العلامة التجارية الجديدة نقطة المشار إليها في ذاكرة واحدة فقط استخدامه هو المتصل دخول الممتلكات الخاصة بك. مع وجود متغير أعلن الكائنات الخاصة بك على الصعيد العالمي، وسوف يكون دائما نفس النقطة في الذاكرة وقفل يمكن التحقق من صحة في الواقع، أن الواقع، هذه النقطة في الذاكرة إما مغلق حاليا أو أنه يمكن قفله هو النفس.

وعلى سبيل المثال: (الخام ولكن اعتقد انه يحصل على نقطة واحدة)

وObject obj = new object();

والآن لديك نقطة في الذاكرة التي يبدو كيندا:

والذاكرة -

    * obj1

والآن قمت بإدخال الممتلكات الخاصة بك مرة أخرى وإنشاء كائن جديد مرة أخرى. ذاكرة النظام الخاص بك الآن يبدو كيندا مثل ...

والذاكرة -

   * obj1
   * obj2

في أول رحلة، قفل الخاص بك هو التحقق "Obj1" في الذاكرة. منذ المتصل من رحلة 1ST في الممتلكات الخاصة بك هو واحد فقط باستخدام تلك الحالة من الكائنات، هو الوحيد الذي من أي وقت مضى أن قفل أو التحقق من ذلك لقفل. لأنه يبحث في هذه النسخة من أن الإشارة الكائنات في الذاكرة.

في الرحلة الثانية، يتم checkign القفل الخاص بك "Obj2" في الذاكرة.

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

ملاحظة خاصة: أنا لا تفيد فترة حياة "الكائنات". أنا مجرد ذكر كيف أن هذا هو functiong في عملية مترابطة متعددة. نأمل أن يساعد.

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