Сохраните настройки в синхронизации между приложением форм и сервисом окон (или любой n-tier, действительно)

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

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

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

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

5
задан SqlRyan 2 July 2010 в 19:59
поделиться

2 ответа

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

Но я работаю только в .NET 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
3
ответ дан 14 December 2019 в 04:29
поделиться

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

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

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

2
ответ дан 14 December 2019 в 04:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: