Сохранение потока XML в C# говорит о том, что он используется другим процессом.
Вопрос
У меня есть этот библиотека с открытым исходным кодом, и у меня возникли проблемы с решением проблемы...Эта библиотека позволяет легко создать 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 у вас «может» возникнуть конфликт в отношении файла, и вам потребуется поместить код сохранения в оператор блокировки.Этот метод по своей природе нереентерабельен, поскольку файл является общим ресурсом.Если у вас нет нескольких потоков, установка блокировки может оказаться чрезмерным убийством, но вы должны быть уверены, что правильно контролируете доступ к файлу.
Еще одна вещь, которую следует учитывать, — это то, что вам может потребоваться переместить операцию сохранения в фоновый поток для записи файла.Если вы получаете большой файл настроек, вы можете вызвать странные взаимодействия с пользовательским интерфейсом, поскольку вы ожидаете записи файла каждый раз, когда пользователь изменяет размер, и это происходит в потоке пользовательского интерфейса.Если вы это сделаете, вам обязательно потребуется заблокировать доступ к файловому ресурсу.
Также вы можете попробовать использовать оператор блокировки.Возможно, методы опережают друг друга.