Держите настройки в синхронизации между приложением форм и службой Windows (или любого N-уровня, действительно)

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

Вопрос

У меня есть служба Windows, которая выполняет ряд периодических действий, и я хочу изменить настройки этой услуги из приложения Windows Forms. Хотя я не уверен, что о лучшем способе убедиться, что у службы есть самые обновленные пользовательские настройки в нем (как часто запустить, какие папки для использования для вещей, что бы ни уточнить пользователь). Пользователь может изменить настройки в любое время, по желанию, и я хотел бы, чтобы служба узнала об этом почти немедленно. Вот варианты, которые я весом:

  1. Область формы и обслуживания используют те же объект «Настройки» из третьего общего проекта, и форма использует вызов WCF «Обновления (газеты)», чтобы позволить услуги знать, что были изменения (или, необязательно, вызов Обновите каждой отдельной настройки, хотя это похоже на разные звонки). В настоящее время я использую WCF для базовых сообщений, но объект настроек может быть огромным, так как там много других вещей
  2. Форма и сервис используют общий файл конфигурации (XML или те же объект настроек из # 1, но для сериализации на диск). Форма только что пишет новую копию объекта после того, как она была изменена, и обслуживание проверяет каждый часто и выбирает его, если это новое, обновление его копии настроек
  3. То же самое, что и № 2, но с базовым вызовом WCF, который говорит службу, чтобы получить настройки. По сути, «по требованию» вместо «опроса» версии № 2.

Я знаю, лучше всего субъективно, но я заинтересован в каких-либо очевидных профазных по причинам для этих вариантов. Поскольку мне придется сохранить свои настройки между контактами приложения (перезагрузки и т. Д.), Мне нужно в любом случае сериализовать настройки на диск, поэтому я уже прилагаюсь к # 2 или # 3. Мне нужно место на диске, где я могу сохранить настройки, но, возможно, папка AppData будет работать в порядке, хотя это позволит администраторам только сменить настройки, поскольку они единственные, которые имеют разрешение на запись в это место (где каждый пользователь, включая учетную запись службы, может прочитать его).

Спасибо за ваше понимание!

Это было полезно?

Решение

Я использую свой номер 2.

Но я работаю только в .NET 2 с моим приложением, но он все равно должен применять.

У меня есть класс настроек, которые я использую в моих 2 программах. Внутри этого класса настроек я настроил FileSystemwatcher. Объект, который смотрит на файл настроек.

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

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

Я использую AppData (My Company / Directory Name Application) для хранения файла.

Другое, что нужно иметь в виду, в том, что на файле можно заблокировать, когда он написан, чтобы вы могли использовать файл Temp Save, удалять старый, переименовать метод Temp или поместить некоторые защитные блокировки в файл при чтении после Событие FileWatcher срабатывает, что изменения были сделаны.

Я использую этот подход в моем FileSystemwatcher. перед продолжением

IPSDependency.FileSystem.WaitForLockOnFile(Me.mFilePath)

Код для этого похож на это. (При чтении этого теперь может быть лучший метод, который мой сплю здесь, чтобы уменьшить перемагни ЦП)

Public Shared Function IsLockAvailable(ByVal filename As String, ByVal fnfIsOK As Boolean) As Boolean
    Dim fi As FileInfo
    fi = New FileInfo(filename)
    Return IsLockAvailable(New FileInfo(filename), fnfIsOK)
End Function

Public Shared Function IsLockAvailable(ByVal theFile As FileInfo, ByVal fnfIsOK As Boolean) As Boolean
    Dim fs As FileStream
    Try
        If theFile.Exists Then
            fs = New FileStream(theFile.FullName, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
            fs.Close()
            Return True
        Else
            Return fnfIsOK
        End If
    Catch ex As IOException
        'we just let the exception go, because we are only testing the file rather than trying to use it.
        Return False
    End Try
End Function

Public Shared Sub WaitForLockOnFile(ByVal theFilename As String)
    WaitForLockOnFile(New FileInfo(theFilename))
End Sub

Public Shared Sub WaitForLockOnFile(ByVal theFile As FileInfo)
    Dim lockAvailable As Boolean
    If theFile.Exists Then
        While Not lockAvailable
            lockAvailable = IsLockAvailable(theFile, False)
        End While
    End If
End Sub

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

Предполагая, что все работает на одной машине, как насчет этого:

  1. Определите общую структуру C #, которая определяет настройки. Все проекты включают в себя этот файл .cs. Определите этот класс как распределять с А. Structlayout. из Последовательный или Явный Таким образом, он может быть сопоставлен непосредственно в неуправляемую общую память. Например:

    Structlayout (layoutkind.s.somential)] Небезопасная структура MySharedSettings {Public int Setting1; публично int set2; Общественная строковая настройка3; // Добавить больше полей здесь. }

  2. Использовать названа общая память (АКА: Памятные файлы). Это позволяет нескольким процессам на одном компьютере для обмена данными, без накладных расходов Удаленность или WCF.. Отказ Общая память чрезвычайно быстры и, в отличие от труб, предлагает произвольный доступ к общим данным памяти. Служба создаст названную общую память, а приложения пользовательского интерфейса откроют совместную память. Вам придется использовать PINVOOKE, чтобы использовать основные API в Windows, но это не имеет большого значения.

  3. Приложения пользовательского интерфейса написать MySharedSettings для общей памяти, а служба прочитает общую память.

  4. Использовать Названный семафор и / или по имени Mutex. Чтобы защитить доступ к общей памяти и сигнализировать о наличии новых настроек. Услуга имеет специальную фоновую резьбу, которая просто выполняет WaiteNe () на семафоре, а поток пользовательского интерфейса будет сигнален при написании новых данных.

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

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

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

Я должен согласиться с вашим начальным наклонным к # 2 и # 3. Мне особенно нравится # 3, так как я не фанат опроса, но в конечном итоге я думаю, что решение между № 2 или № 3 будет обусловлено требованиями вашего обслуживания.

Что касается хранения пользовательских настроек, я бы рекомендовал исследовать изолированное хранилище ( http://msdn.microsoft.com/en-us/library/3ak841sy.aspx. ). Он обеспечивает отличный механизм для безопасного, последовательного и надежного доступа к пользовательским файлам. Вам не придется беспокоиться о разрешении пользователя, если только администратор не полностью отключил изолированное хранилище. Кроме того, если вы включите роуминг, пользователи могут даже принять их настройки, если они используют разные системы в том же домене, довольно Slick EH?

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