Как несколько процессов на разных компьютерах с Windows должны одновременно использовать файл, хранящийся в общем каталоге?

Проблема:

У меня есть несколько экземпляров одного и того же приложения C #, запущенного на разных компьютерах (ОС: Windows XP, Windows 7) в одной локальной сети. Я должен поделиться между ними некоторыми данными конфигурации. Каждый процесс должен иметь доступ для чтения и записи к данным. Мой работодатель настаивает на хранении этих общих данных в файле, который находится в общем каталоге на одном из этих компьютеров.

Возможные решения:

  1. Эксклюзивное открытие файла: Данные хранятся в файле TXT (также возможна сериализация в двоичный файл и обратно). Каждый процесс использует File.Open с FileShare.None при попытке открыть файл. Получение IOException означает, что файл уже используется, поэтому процесс должен подождите и повторите попытку позже.
  2. Встроенная база данных SQL Server CE: данные хранятся в файле SDF. Движок может обрабатывать не более 256 одновременных подключений (v3.5 SP2), что более чем достаточно.
  3. встроенная база данных SQLite: данные хранятся в файле базы данных SQLite. В документации говорится, что SQLite работает, но может быть ненадежным при использовании в общей сетевой папке.
  4. Другой?

Каков предпочтительный способ сделать это?


person kol    schedule 22.01.2012    source источник
comment
Ваши параметры SQL Server CE и SQLite сообщают мне, что вы можете контролировать формат файла данных. Это правда?   -  person M.Babcock    schedule 22.01.2012
comment
@ M.Babcock Да. Это разработка.   -  person kol    schedule 22.01.2012
comment
Какую версию .NET вы используете в своей разработке?   -  person M.Babcock    schedule 22.01.2012
comment
@ M.Babcock Меня попросили использовать .NET 2.0, но при необходимости можно переключиться на .NET 4.   -  person kol    schedule 22.01.2012
comment
SQL Server CE не работает одновременно в сети, он работает только на одном компьютере. Не совсем вариант для вас.   -  person Joel Lucsy    schedule 22.01.2012
comment
@JoelLucsy - Даже из сетевой папки?   -  person M.Babcock    schedule 22.01.2012
comment
@JoelLucsy Я уже пробовал использовать SSCE через общий сетевой ресурс, и это сработало. Что вы имеете в виду под словом «не одновременный»?   -  person kol    schedule 22.01.2012
comment
@kol: Итак, вам повезло, и у вас не было двух компьютеров, записывающих файл одновременно. Не рассчитывай, что тебе всегда повезет.   -  person Ben Voigt    schedule 22.01.2012


Ответы (3)


Не знаю, лучший ли это способ, но я сделал это на C много лет назад, у меня это хорошо сработало.

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

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

Каждый процесс перезагружает файл (содержащий информацию, поступающую от всех других процессов).

Конечно, это решение требует, чтобы процесс записи файла знал, как восстановить файл и как разрешать конфликты (но это зависит от формата данных).

person BigMike    schedule 22.01.2012
comment
+1 за идею личных экземпляров. К сожалению, я не могу использовать мастер-процесс. Требуется, чтобы все процессы имели одинаковые права и не могли связываться друг с другом по сети. - person kol; 22.01.2012
comment
Даже размещение данных в базе данных не решит полностью проблемы доступа к ресурсам (но упростит управление). Как часто происходит обновление файла? - person BigMike; 22.01.2012
comment
Забавно, но я привыкаю к ​​идее мастер-процесса :) - person kol; 22.01.2012
comment
@BigMike: Это зависит от движка базы данных. Jet, например, явно поддерживает этот сценарий. - person Ben Voigt; 22.01.2012
comment
@BenVoigt Спасибо за ссылку! - person kol; 22.01.2012
comment
@BenVoigt: интересно читать. На ум приходит старый добрый btree, используемый для обеспечения параллелизма и блокировки уровня записи. Использование db (даже db на основе файлов) упрощает управление блокировками, но проблема все еще существует. JET допускает грязное чтение, но это зависит от приложения access / vb, чтобы убедиться, что данные согласованы между всеми потребителями. Даже с Oracle или DB2 (немного более сложным механизмом баз данных, чем JET) параллелизм является серьезной проблемой, и ее следует принимать во внимание. - person BigMike; 23.01.2012
comment
@BigMike: По крайней мере, приложение может позаботиться о параллелизме на уровне записей. Несоответствия в индексах и распределении, скорее всего, будут иметь место, если ядро ​​базы данных не предназначено для одновременного удаленного доступа, и приложение не молится о преодолении такого рода повреждений. - person Ben Voigt; 23.01.2012
comment
@BenVoigt: да, конечно, я просто имел в виду параллелизм доступа к данным. Доступ к мультимедиа (файлы данных или что-то еще, что является базовым хранилищем) - это совершенно другое дело. - person BigMike; 23.01.2012

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

Лучше всего использовать для этого подходящую СУБД, если данные, с которыми вы работаете, обычно можно считать ориентированными на записи / поля (а в редких случаях даже если это не так). В этом случае я бы порекомендовал MSSQL CE, поскольку его среда выполнения решит для вас проблемы с многопользовательской работой.

SQLite обычно считался базой данных для одного пользователя / приложения (по крайней мере, когда я использовал его в C), хотя за последние 5 лет все могло измениться. Если вы используете .NET 4, то есть несколько бесплатных адаптеров, доступных для использования из того, что я нашел, если вам не удобно работать со смешанным фреймворком.

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

person M.Babcock    schedule 22.01.2012
comment
+1 за упоминание библиотек журналов, я их проверю. Общий набор данных очень прост, он похож на одну таблицу БД (записи с одинаковыми полями). - person kol; 22.01.2012
comment
В качестве альтернативы было бы несложно написать оболочку веб-службы поверх SQLite API, которая могла бы обеспечить параллелизм для вас. Библиотеки журналов обычно предназначены только для записи (что, по общему признанию, является сложной частью того, что вы пытаетесь выполнить), поэтому, если вы можете освоить это, должно быть достаточно просто для совместного чтения. - person M.Babcock; 22.01.2012
comment
Веб-сервис - хорошая идея, но я должен использовать самый простой из возможных подходов. Мой работодатель предпочитает копирование и вставку небольших исполняемых файлов и не хочет использовать установщики, веб-службы и т. Д. - person kol; 22.01.2012
comment
Есть ли у вас источник, подтверждающий, что MSSQL CE обрабатывает блокировку с нескольких компьютеров? - person Ben Voigt; 22.01.2012
comment
@kol: развертывание с копированием и вставкой не препятствует открытию прослушивающего сокета. Но как вы найдете основной файл конфигурации в сети при развертывании с копированием и вставкой? Текстовый файл в каталоге приложения, который копируется вместе с исполняемым файлом? - person Ben Voigt; 22.01.2012
comment
@BenVoigt - Не напрямую, хотя я легко использовал его в аналогичной среде. По общему признанию, в ситуации с низким уровнем записи, но, похоже, это сработало. Я указал его только как предложенный вариант, потому что это был один из предложенных вариантов (помимо «Другие»). Если бы у меня был выбор, я бы выбрал полноценный дистрибутив MSSQL (или даже одну из бесплатных альтернатив). - person M.Babcock; 22.01.2012
comment
@CharlesLambert Он не разработчик программного обеспечения. В любом случае это проект vworker.com, так что после того, как я закончу работу, у меня будет другой работодатель :) - person kol; 22.01.2012
comment
@BenVoigt У меня есть простые тестовые программы для всех трех вариантов. Я думаю, мне следует провести стресс-тестирование каждого метода, а после теста проверить, выглядят ли общие данные так, как должны. - person kol; 22.01.2012
comment
@BenVoigt Microsoft утверждает, что SSCE поддерживает хранение файлов БД на сетевом ресурсе: download.microsoft.com/download/A/4/7/ - person kol; 22.01.2012
comment
@kol: Это не значит, что он используется одновременно с нескольких компьютеров. Это означает, что вы можете хранить файл данных в вашем домашнем каталоге (на сетевом сервере, для автоматического резервного копирования), где только один клиент использует его одновременно. Представления файла согласованы между процессами на одном компьютере, даже если файл удален. Но взгляды с разных удаленных компьютеров не согласованы. Для реализации удаленной блокировки требуется дополнительная работа. - person Ben Voigt; 22.01.2012
comment
Обратите внимание: я не говорю, что MSSQLCE не поддерживает этот сценарий. Просто предоставленный вами документ неубедителен. - person Ben Voigt; 22.01.2012
comment
@BenVoigt - Значит, вам повезло, и у вас не было двух компьютеров, записывающих файл одновременно. не говорит этого? - person M.Babcock; 22.01.2012

Создайте веб-службу и заставьте свои программы извлекать конфигурацию оттуда. Вы можете управлять блокировкой файлов изнутри веб-службы, и вам не придется иметь дело с этим на программном уровне. Это также дает вам абстракцию: если вы решите изменить способ хранения настроек (например, переместить их из файла в базу данных), вы можете сделать это, не внося никаких изменений в свою программу.

person Charles Lambert    schedule 22.01.2012