Сохранение потока XML в C# говорит о том, что он используется другим процессом.

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

  •  21-08-2019
  •  | 
  •  

Вопрос

У меня есть этот библиотека с открытым исходным кодом, и у меня возникли проблемы с решением проблемы...Эта библиотека позволяет легко создать XML-файл для хранения настроек приложения.Но у меня возникла проблема с сохранением изменений.

У меня есть другое приложение, в котором я использую эту библиотеку, и каждый раз, когда размер окна приложения изменяется, я вызываю метод Save() библиотеки, чтобы сохранить размер/положение окна в файл XML.

В большинстве случаев все работает нормально, все сохраняется.Однако время от времени я получаю исключение, сообщающее, что файл используется другим процессом.

Мне действительно нужно убедиться, что изменения сохраняются каждый раз при вызове метода Save(), мне нужно как-то обработать это исключение или предотвратить его возникновение.

Какие у вас предложения, ребята, как лучше всего справиться с этой ситуацией?

Код метода Save() следующий:

public void Save() {
    // Create a new XML file if there's no root element
    if(xDocument.DocumentElement == null) {
        xDocument = new XmlDocument();
        xDocument.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
            "<" + XmlRootElement + ">\n</" + XmlRootElement + ">");
    }

    // OMITTED CODE WAS HERE (NOT IMPORTANT FOR THE PROBLEM)

    // Create a new XML writer for the XML file
    XmlWriter xWriter = XmlWriter.Create(XmlFilePath, new XmlWriterSettings() {
        Indent = true,
        IndentChars = "\t"
    });

    // Sort the XML file using the XSL sylesheet and save it
    xslTransform.Transform(xDocument, xWriter);

    // Clear the buffer and close the XML writer stream
    xWriter.Flush();
    xWriter.Close();
}
Это было полезно?

Решение

Возможно, события завершения изменения размера окна срабатывают так быстро, что вызывается функция сохранения, вызываемая снова, прежде чем она завершится в первый раз.Это приведет к ошибке, которую вы описываете (другой процесс, использующий файл...ТЫ!). Попробуйте окружить свой код замком, таким образом:

lock(some_shared_object)
{
    //Your code here
}

Другие советы

XmlWriter является IDisposable.Вам следует обернуть его в предложение using().http://msdn.microsoft.com/en-us/library/system.xml.xmlwriter.aspx

Мне придется использовать комбинацию ответов, уже приведенных здесь.

Ваш XmlWriter должен находиться в блоке использования по нескольким причинам.Вам следует распорядиться им так, чтобы ваши ресурсы освободились как можно скорее.Кроме того, что, если вы создадите исключение во время взаимодействия с ним.Файл не будет закрыт должным образом, по крайней мере, до тех пор, пока не сработает финализатор и не освободит ваши ресурсы.

Даже при использовании оператора using у вас «может» возникнуть конфликт в отношении файла, и вам потребуется поместить код сохранения в оператор блокировки.Этот метод по своей природе нереентерабельен, поскольку файл является общим ресурсом.Если у вас нет нескольких потоков, установка блокировки может оказаться чрезмерным убийством, но вы должны быть уверены, что правильно контролируете доступ к файлу.

Еще одна вещь, которую следует учитывать, — это то, что вам может потребоваться переместить операцию сохранения в фоновый поток для записи файла.Если вы получаете большой файл настроек, вы можете вызвать странные взаимодействия с пользовательским интерфейсом, поскольку вы ожидаете записи файла каждый раз, когда пользователь изменяет размер, и это происходит в потоке пользовательского интерфейса.Если вы это сделаете, вам обязательно потребуется заблокировать доступ к файловому ресурсу.

Также вы можете попробовать использовать оператор блокировки.Возможно, методы опережают друг друга.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top