Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 保持窗体应用程序和windows服务(或任何n层)之间的设置同步_.net_Wcf_Serialization_Application Settings_Multi Tier - Fatal编程技术网

.net 保持窗体应用程序和windows服务(或任何n层)之间的设置同步

.net 保持窗体应用程序和windows服务(或任何n层)之间的设置同步,.net,wcf,serialization,application-settings,multi-tier,.net,Wcf,Serialization,Application Settings,Multi Tier,我有一个执行许多定期活动的Windows服务,我想从Windows窗体应用程序更改此服务的设置。不过,我不确定确保该服务具有最新用户首选项的最佳方式(运行频率、使用哪些文件夹、用户可以指定的其他内容)。用户可以随时随意更改设置,我希望服务人员能立即了解。以下是我正在权衡的选项: 表单和服务共享使用来自第三个共享项目的相同“设置”对象,表单使用WCF“UpdateSettings(newSettings)”调用让服务知道已经发生了更改(或者,可选地,调用更新每个单独的设置,尽管这似乎比不同的调用要

我有一个执行许多定期活动的Windows服务,我想从Windows窗体应用程序更改此服务的设置。不过,我不确定确保该服务具有最新用户首选项的最佳方式(运行频率、使用哪些文件夹、用户可以指定的其他内容)。用户可以随时随意更改设置,我希望服务人员能立即了解。以下是我正在权衡的选项:

  • 表单和服务共享使用来自第三个共享项目的相同“设置”对象,表单使用WCF“UpdateSettings(newSettings)”调用让服务知道已经发生了更改(或者,可选地,调用更新每个单独的设置,尽管这似乎比不同的调用要多)。我目前使用WCF处理基本消息,但是设置对象可能很大,因为里面有很多其他东西
  • 表单和服务使用公共配置文件(XML,或来自#1的相同设置对象,但已序列化到磁盘)。表单只是在对象被更改后写入一个新的副本,服务每隔一段时间检查一次,如果它是新的,就把它捡起来,更新它的设置副本
  • 与#2相同,但有一个基本的WCF调用,告诉服务去获取设置。本质上,是一个“按需”而不是“轮询”版本的#2
  • 我知道最好是主观的,但我对这些选择的任何明显的赞成或反对理由感兴趣。由于我必须在应用程序运行(重新启动等)之间保存设置,因此我必须将设置序列化到磁盘,因此我已经倾向于使用#2或#3。我需要一个可以保存设置的磁盘上的位置,但是AppData文件夹可能可以正常工作,尽管这只允许管理员更改设置,因为他们是唯一有权写入此位置(包括服务帐户在内的每个用户都可以读取此位置)的人


    谢谢你的洞察力

    我有点用你的号码2

    但我只在.NET2中使用我的应用程序,但它应该仍然适用

    我有一个设置类,我在我的两个程序中使用。在这个设置类中,我设置了一个查看设置文件的对象

    如果其他应用程序更新了设置文件,my current将获得一个事件触发器,指示需要重新加载设置

    您还可以在设置屏幕中应用相同的原则,这样,如果(服务)其他应用程序在设置编辑期间更新了任何内容,这些内容将反映在您的屏幕中

    我使用AppData(我的公司/应用程序名称目录)存储文件

    要记住的另一件事是,文件在写入时可能会被锁定,因此您可以使用temp name save、delete old、rename temp方法,或者在filewatcher事件触发更改后读取时对文件进行一些保护性锁定

    在继续之前,我在我的工作中使用此方法

    IPSDependency.FileSystem.WaitForLockOnFile(Me.mFilePath)
    
    代码是这样的。(现在读到这篇文章后,可能有一个更好的方法,我在这里使用一些睡眠来减少CPU抖动)


    通常,执行“轮询操作”(即同步文件)的服务在其轮询间隔中有足够的延迟时间,您可以在每个循环中或根据需要轻松地重新读取所有设置

    如果您的服务更接近SOA后端,那么更改可能会影响通常在服务生命周期中只使用一次的设置。如果这是您的应用类型,那么您上面描述的选项#2是最可靠的。我不能说我很关心Paul的实现,因为轮询这样的文件会产生不可靠的结果。我建议使用一个全局命名的等待句柄来通知您的流程进行更改。我相信你可以在这里找到一个这样的例子。如果不想这样做,则可以轮询配置文件的上次修改时间更改


    总的来说,我倾向于第一种使用注册表进行存储的方法。在注册表配置单元中以离散值写入所有设置,并在服务中按需读取它们。它比你想象的要快,而且在前端和后端都很容易实现。

    我同意你最初倾向于第2和第3条。我特别喜欢#3,因为我不喜欢投票,但最终我认为#2或#3之间的决定将取决于您的服务要求


    至于用户设置的存储,我建议探索独立存储()。它为安全、一致和可靠地访问用户文件提供了极好的机制。除非管理员完全关闭了独立存储,否则您不必担心用户是否拥有权限。另外,如果你启用漫游功能,用户甚至可以在同一个域上使用不同的系统时随身携带他们的设置,这很巧妙吧

    假设所有的东西都在同一台机器上运行,那么这个呢:

  • 定义定义设置的通用c#结构。所有项目都包含此.cs文件。将该类定义为一个结构,其结构布局顺序显式,因此它可以直接映射到非托管共享内存中。例如:

    [StructLayout(LayoutKind.Sequential)] 不安全的结构MySharedSettings { 公共int设置1; 公共int设置2; 公共字符串设置3; //在此处添加更多字段。 }

  • 使用命名共享内存(也称为内存映射文件)。这允许同一台计算机上的多个进程共享数据,而无需远程处理WCF的开销。共享内存速度非常快,与管道不同,它提供对共享内存数据的随机访问。这项服务真是太棒了
    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