Сохранение потока XML в C # говорит, что он используется другим процессом - PullRequest
1 голос
/ 11 мая 2009

У меня есть эта библиотека с открытым исходным кодом, у меня возникли проблемы с решением проблемы ... Эта библиотека позволяет легко создавать 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();
}

Ответы [ 4 ]

3 голосов
/ 11 мая 2009

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

2 голосов
/ 12 мая 2009

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

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

Даже с помощью оператора using у вас может возникнуть конфликт по файлу, и вам нужно поместить код сохранения в оператор блокировки. Метод не реентерабелен по своей природе, поскольку файл является общим ресурсом. Установка блокировки вокруг него может быть чрезмерной, если у вас нет нескольких потоков, но вы должны убедиться, что вы правильно контролировали доступ к файлу.

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

1 голос
/ 11 мая 2009

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

lock(some_shared_object)
{
    //Your code here
}
1 голос
/ 11 мая 2009

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

...