请设置在表单应用程序和窗口服务之间同步(或n层,真)

请设置在表单应用程序和窗口服务之间同步(或n层,真)

问题描述:

我有一个Windows服务,它执行了一些周期性的活动,我希望从Windows中更改该服务的设置窗体应用程序。我不知道,不过,要确保服务在其最新的用户preferences(频率运行,用的东西,任何其他用户可以指定哪些文件夹)的最佳方式。用户可以随时更改设置,随意,我想服务了解它几乎立即。下面是我在权衡选项:

I have a Windows Service that performs a number of periodic activities, and I want to change the settings of this service from a Windows Forms app. I'm not sure, though, about the best way to make sure the service has the most updated user preferences in it (how often to run, what folders to use for things, whatever else the user can specify). The user can change settings any time, at will, and I'd like the service know about it almost immediately. Here are the options I'm weighing:

  1. 的形式和服务共享使用从第三,共享项目相同的设置对象,形式使用WCFUpdateSettings(newSettings)打电话让服务知道发生了变化(或可选,一个叫更新每个单独的设置,虽然这似乎是很多在不同的调用)。我目前使用WCF的基本信息,但设置对象可以是巨大的,因为有很多其他的东西在里面
  2. 在形式和服务使用一个公共的配置文件(XML,或者从#1的相同设置对象,但序列化到磁盘)。表单只是将对象的新副本,它已经改变了之后,和服务检查,每隔一段时间,将它拾起,如果它是新的,更新的设置及其复印件
  3. 同#2,但具有基本的WCF呼叫,它告诉服务去获得的设置。从本质上讲,一个按需,而不是轮询版本中排名第2。

我知道最好的是主观的,但我感兴趣的任何明显的赞成或反对的理由为这些选择。因为我得保存应用程序(重新启动等)的跑道之间我的设置,我将不得不反正序列化的设置保存到磁盘,所以我已经对#2或#3倾斜。我需要在磁盘上的一个地方,我可以保存设置,但也许在应用程序数据文件夹,将工作好,虽然这将只允许管理员更改设置,因为他们是唯一的,有权写入到该位置(其中每一个用户,包括服务帐户,可以读取它)。

I know best is subjective, but I'm interested in any obvious pro or con reasons for these choices. Since I'll have to save my settings between runnings of the application (reboots, etc), I'll have to serialize the settings to disk anyway, so I'm already leaning towards #2 or #3. I'll need a place on disk where I can save the settings, but maybe the AppData folder will work okay, though that will only allow Administrators to change the settings, since they're the only ones that have permission to write to this location (where every user, including the service account, can read it).

感谢您的见解!

我有点儿用你的号码2。

I kinda use your number 2.

但我唯一的工作在.NET 2我的应用程序,但它应该仍然适用。

But I'm only working in .NET 2 with my application, but it should still apply.

我有我在我的两个程序使用一个设置类。在这个设置Ⅰ类设置一个 FileSystemWatcher的的对象,看起来在设置文件。

I have a settings class that I use across my 2 programs. Inside this settings class I setup a FileSystemWatcher object that looks at the Settings file.

如果设置文件是由其他应用程序进行更新,我的当前获取一个事件触发,以指示设置需要装填。

If the settings file is updated by the other application, my current gets an event trigger to indicate that the settings need to reload.

您也可以采用同样的原则在你的设置画面,因此如果设置编辑期间(服务)等应用程序更新任何东西,这反映在您的屏幕。

You can also apply the same principle in your settings screen so that if the (service) other application updates anything during the settings edit, that is reflected in your screen.

我用的是应用程序数据(我公司/应用程序名称的目录)来存储文件。

I use the AppData (my company/application name directory) to store the file.

另外要记住的是,可以有锁定的文件,当它被写入,所以你可以使用一个临时名称保存,删除旧,重命名临时方法或放一些保护锁上的文件时,在filewatcher事件发生后阅读大火已经作了修改。

The other thing to bear in mind, is that there can be locking on the file while it is being written so you can either use a temp name save, delete old, rename temp method or put some protective locking on the file when reading after the filewatcher event fires that changes have been made.

我用这种方法在我的 FileSystemWatcher的前出发

I use this approach in my FileSystemWatcher before proceeding

IPSDependency.FileSystem.WaitForLockOnFile(Me.mFilePath)

在$ C $下是这样的。 (在今读这篇文章,有可能是我使用一些睡在这里,以减少CPU的颠簸一个更好的方法)

the code for that is like this. (upon reading this now, there may be a better method my using some sleep in here to reduce CPU thrashing)

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