Синхронизируйте настройки между приложением форм и службой Windows (или вообще любым n-уровневым) - PullRequest
5 голосов
/ 02 июля 2010

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

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

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

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

Ответы [ 4 ]

3 голосов
/ 24 июля 2010

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

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

    [StructLayout (LayoutKind.Sequential)] небезопасная структура MySharedSettings {public int setting1;public int setting2;настройка публичной строки3;// добавить больше полей здесь.}

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

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

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

3 голосов
/ 19 июля 2010

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

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

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

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

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

Я использую AppData (каталог с именем моей компании / приложения) для хранения файла.

Еще одна вещь, которую нужно иметь в виду, это то, что во время записи файла может быть блокировка, так что вы можете использовать временное имя для сохранения, удалить старый, переименовать временный метод или установить некоторую защитную блокировку файла чтение после того, как событие 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
2 голосов
/ 20 июля 2010

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

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

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

0 голосов
/ 23 июля 2010

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

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

...