в моем приложении (C# 3.5) различные процессы очень часто обращаются к одному XML-файлу (чтение и запись). код доступа к файлу помещается в сборку, на которую ссылается довольно много других приложений. например, служба Windows может создать экземпляр класса MyFileReaderWriter (расположенный в ранее упомянутой сборке) и использовать методы чтения / записи этого класса.
Я ищу лучший / самый быстрый способ читать и создавать / добавлять файл с наименьшим количеством блокировок. Кэширование данных файлов и периодическая очистка нового содержимого не подходят, поскольку данные критически важны.
Я забыл упомянуть, что в настоящее время я использую XDocument (инфраструктура LInq2Xml) для чтения / записи содержимого в файл.
Если подумать, разве это не говорит о проблеме программирования? Даже если фактический ввод-вывод диска не является проблемой, существует риск, что один поток блокирует файл, читает, делает что-то еще, а затем возвращается, записывает результат и снимает блокировку. Между тем все остальные потоки заблокированы.
Есть ли причина, по которой вы не можете использовать БД?
@biozinc: будет несколько процессов, обращающихся к файлу, но не несколько потоков в одном процессе. Насколько я понимаю, это не проблема многопоточности, а проблема "контроля доступа к файлам".
@NM: да, к сожалению, я не могу использовать db по разным причинам. это должен быть файл xml.





Для начала убедитесь, что весь доступ к XML-документу осуществляется через один экземпляр.
Затем поместите механизм блокировки (который ожидает разблокировки) в начале функции, которая обращается к нему, и разблокирует его в конце.
Что вы имеете в виду, что данные критичны? XML-файл не используется исключительно вашим приложением?
Самый простой (и, возможно, достаточно хороший) способ заблокировать доступ ввода-вывода к файлу - это создать статический фабричный класс, который предоставляет объект «токен чтения-записи», который должен блокироваться для каждой операции ввода-вывода.
public static object GetReadWriteToken(String fileName)
{
//use a hashtable to retreive an object, with filename as key
return token;
}
и просто сделайте это во время чтения и записи:
lock(GetReadWriteToken(@"C:\important.xml"))
{
//io code
}
Если, написав, вы только добавляете в документ, попробуйте это
http://msdn.microsoft.com/en-us/library/aa302289.aspx
В основном ваш XML-документ представляет собой оболочку с начальным и конечным тегами. Между тегами находится ссылка включения, которая ссылается на другой файл, этот другой файл является телом XML-документа. Для операций записи это происходит во много раз быстрее, потому что вам не нужно загружать XML-файл каждый раз, когда вы пишете в него, и вы не записываете каждый раз весь файл.
Используя класс XmlWriter, вы можете очень легко добавлять узлы в конец основного файла.
Когда другие хотят прочитать xml, они просто открывают документ, их синтаксический анализатор xml «знает», что нужно загружать и анализировать оба файла.
Надеюсь это поможет.
Несколько дней назад я столкнулся с похожим «состоянием», с нетерпением жду ответов :)