ما هي أفضل طريقة لمزامنة وصول XmlWriter إلى ملف لمنع IOExceptions؟

StackOverflow https://stackoverflow.com/questions/442235

سؤال

توجد أماكن متعددة في أحد التطبيقات التي تستدعي XmlWriter.Create على نفس الملف، ويمكن الوصول إليها جميعًا من خلال الوظيفة التالية.عندما يتصل أحد الأشخاص بينما لا يزال الآخر يكتب، أحصل على IOException.ما هي أفضل طريقة لقفل الوصول أو مزامنته؟

إليك الوظيفة التي يتم استخدامها:

        public void SaveToDisk()
    {
        try
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            using (XmlWriter writer = XmlWriter.Create(SaveFileAbsolutePath, settings))
            {
                XamlWriter.Save(this, writer);
                writer.Close();
            }

        }
        catch (Exception ex)
        {
            // Log the error
            System.Diagnostics.Debug.WriteLine(ex.Message);

            // Rethrow so we know about the error
            throw;
        }
    }

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

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

المحلول

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

private static readonly object syncLock = new object();

public void SaveToDisk()
{
     lock(syncLock)
     {
          ... write code ...
     }
}

public void ReadFromDisk()
{
     lock(syncLock)
     {
          ... read code ...
     }
}

نصائح أخرى

يجب أن يؤدي القفل الثابت المهمة بسرعة وببساطة:

private static readonly object syncLock = new object();

ثم...

public void SaveToDisk()
{
    lock(syncLock)
    {
        ...your code...
    }
}

تستطيع ايضا استخذام [MethodImpl(MethodImplOptions.Synchronized)] (على ثابتة الطريقة التي تقبل المثيل كوسيطة - على سبيل المثال، طريقة ملحقة)، ولكن القفل الصريح أكثر تنوعًا.

سأستخدم في الواقع أ ReaderWriterLock لتعظيم التزامن.يمكنك السماح لعدة قراء ولكن بكاتب واحد فقط في كل مرة.

private ReaderWriterLock myLock = new ReaderWriterLock();

public void SaveToDisk()
{
     myLock.AcquireWriterLock();
     try
     {
          ... write code ...
     } 
     finally
     {
          myLock.ReleaseWriterLock();
     }
}

public void ReadFromDisk()
{
     myLock.AcquireReaderLock();
     try
     {
          ... read code ...
     } 
     finally
     {
          myLock.ReleaseReaderLock();
     }
}

فقط تأكد من فتح الملف باستخدام مشاركة الملفات. قراءة حتى لا تفشل القراءات اللاحقة.

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