IOExceptionsを防ぐために、ファイルへのXmlWriterアクセス​​を同期する最良の方法は何ですか?

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;
        }
    }

UPDATE:問題はこの関数の呼び出しだけではなく、この関数の書き込み中に別のスレッドがファイルを読み込んでいるようです。読み取り中にファイルに書き込もうとしないようにロックする最良の方法は何ですか?

役に立ちましたか?

解決

ロックを使用すると、同時実行の問題を解決できるため、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();

then ...

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

[MethodImpl(MethodImplOptions.Synchronized)] (拡張メソッドなど、インスタンスを引数として受け入れる static メソッドで)を使用することもできます。しかし、明示的なロックはより汎用的です。

実際に ReaderWriterLock を使用して並行性を最大化します。複数のリーダーを許可できますが、一度に作成できるのは1人のライターのみです。

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();
     }
}

FileShare.Read <でファイルを開いてください。以降の読み取りが失敗しないようにします。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top