Mantener la configuración de sincronización entre la aplicación y formas de servicio de Windows (o cualquier n niveles, en realidad)

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

Pregunta

Tengo un servicio de Windows que realiza una serie de actividades periódicas, y quiero cambiar la configuración de este servicio desde una aplicación de Windows Forms. No estoy seguro, sin embargo, sobre la mejor manera de asegurarse de que el servicio tiene las preferencias de usuario más actualizados en el mismo (con qué frecuencia para funcionar, lo que las carpetas de usar para cosas, cualquier otra cosa que el usuario puede especificar). El usuario puede cambiar la configuración en cualquier momento, a voluntad, y me gustaría saber el servicio de ella casi de inmediato. Estas son las opciones que estoy un peso:

  1. La forma y el uso de servicios comparten el mismo "Configuración" objeto desde un tercer proyecto, compartida y el formulario utiliza un "UpdateSettings (newSettings)" WCF para poder avisar al know servicio que se han producido cambios (o, opcionalmente, una llamada a actualizar cada configuración individual, aunque esto parece mucho a lo largo de diferentes llamadas). Actualmente uso WCF para los mensajes básicos, pero el objeto configuración puede ser enorme, ya que hay un montón de otras cosas allí
  2. Forma y servicio utilizan un archivo de configuración común (XML, o la misma configuración de objeto desde el # 1, pero serializados en el disco). El Formulario simplemente escribe una nueva copia del objeto después de que haya sido cambiado, y las comprobaciones de mantenimiento cada cierto tiempo y lo recoge si es nueva, la actualización de su copia de los parámetros
  3. Igual que el # 2, pero con una llamada WCF básico que dice que el servicio para ir a buscar los ajustes. En esencia, un "on-demand" en lugar de la versión "sondeo" de # 2.

Yo sé mejor es subjetivo, pero estoy interesado en cualesquiera razones obvias favor o en contra de estas opciones. Puesto que voy a tener que guardar mi configuración entre los rodajes de la aplicación (reinicios, etc.), voy a tener que serializar los ajustes en el disco de todos modos, así que ya estoy inclinando hacia # 2 y # 3. Voy a necesitar un lugar en el disco donde puedo guardar los ajustes, pero tal vez la carpeta de datos de programa a trabajar bien, a pesar de que sólo permitirá a los administradores cambiar la configuración, ya que son los únicos que tienen permiso para escribir en esta ubicación (donde cada usuario, incluyendo la cuenta de servicio, puede leerlo).

Gracias por su comprensión!

¿Fue útil?

Solución

La clase I use su número 2.

Pero sólo estoy trabajando en .NET 2 con mi solicitud, pero todavía debe aplicarse.

Tengo una clase de configuración que yo uso a través de mis 2 programas. Dentro de esta clase de configuración de ajustes que un FileSystemWatcher objeto que mira el archivo de configuración.

Si el archivo de configuración se actualiza por la otra aplicación, mi actual recibe un disparador de evento para indicar que los ajustes que volver a cargar.

También se puede aplicar el mismo principio en la configuración de pantalla de modo que si el (servicio) otras actualizaciones de la aplicación nada durante la configuración de edición, que se refleja en la pantalla.

Yo uso el AppData (mi empresa directorio de nombres / aplicación) para almacenar el archivo.

La otra cosa a tener en cuenta, es que no puede haber bloqueo en el archivo mientras se está escribiendo para que pueda utilizar un nombre temporal de guardar, eliminar, el método de la temperatura de cambio de nombre de edad o poner un poco de bloqueo de protección en el archivo cuando leer después de los incendios de evento FileWatcher que se han realizado cambios.

Yo uso este enfoque en mi FileSystemWatcher antes de proceder

IPSDependency.FileSystem.WaitForLockOnFile(Me.mFilePath)

el código para que sea así. (Después de leer esto ahora, puede haber un método mejor mi usando un poco de sueño en aquí para reducir golear CPU)

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

Otros consejos

Si se asume que todo se está ejecutando en la misma máquina, ¿qué tal esto:

  1. Definir un # estructura c común que define la configuración. Todos los proyectos incluyen este archivo .cs. Definir esta clase como un struct con un StructLayout Secuencial o explícita para que pueda ser mapeada en el compartida no administrado memoria. Por ejemplo:

    [StructLayout (LayoutKind.Sequential)] MySharedSettings struct inseguras {     Ajuste1 int pública;     Ajuste2 int pública;     Setting3 cadena pública;     // añadir más campos aquí. }

  2. Uso memoria compartida llamada (aka: archivos asignados en memoria ). Esto permite que varios procesos en el mismo ordenador para compartir datos, sin la sobrecarga de Remoting o WCF . La memoria compartida es extremadamente rápido y, a diferencia de las tuberías, las ofertas de acceso aleatorio a los datos de memoria compartida. El servicio crearía la memoria compartida llamada, y las aplicaciones de interfaz de usuario abriría la memoria compartida. Usted tiene que utilizar PInvoke utilizar la API de Windows subyacente, pero esto no es un gran problema.

  3. Las aplicaciones de interfaz de usuario escriben los MySharedSettings a la memoria compartida, mientras que el servicio lee la memoria compartida.

  4. Utilice un nombre de semáforo y / o nombre mutex para Proteger el acceso a la memoria compartida y para indicar la disponibilidad de nuevos ajustes. El servicio tiene un subproceso de fondo dedicado que simplemente realizar una WaitOne () en el semáforo, y el hilo de interfaz de usuario será la señal cuando se escriben nuevos datos.

Por lo general, los servicios que realizan una 'operación de sondeo' (es decir, archivos de sincronización) tienen suficiente tiempo de retraso en su intervalo de sondeo que se puede con la misma facilidad vuelva a leer todos los ajustes de cada bucle, o incluso, según sea necesario.

Si su servicio es más a lo largo de las líneas de un back-end de SOA, a continuación, los cambios pueden afectar a la configuración que generalmente se usan sólo una vez durante la vida de un servicio. Si esta es tu tipo de aplicación, a continuación, la opción # 2 usted describe arriba es la más fiable. No puedo decir que me importa mucho para la implementación de Pablo como un archivo de votación de esa manera dará resultados poco fiables. Yo recomendaría el uso de un mango de espera a nivel mundial llamado a la señal de su proceso de cambios. Estoy seguro de que puede encontrar un ejemplo aquí en la SO. Si no quieres hacer eso, entonces podría sondear para el cambio de hora de última modificación del archivo de configuración.

En general, mi preferencia es para el primer enfoque mediante el registro para el almacenamiento. Escribir todos los ajustes en los valores discretos en una sección del Registro y leerlos en-demanda en su servicio. Es más rápido de lo que piensa y fácil de implementar en frente y de fondo.

Estoy de acuerdo con su inicial se inclinan hacia # 2 y # 3. Me gusta especialmente el # 3 ya que no soy un fan de la votación, pero en última instancia, creo que la decisión entre el # 2 y # 3 será impulsado por las necesidades de su servicio.

En cuanto al almacenamiento de la configuración del usuario que recomendaría explorar el almacenamiento aislado ( http: //msdn.microsoft.com/en-us/library/3ak841sy.aspx ). Proporciona un excelente mecanismo para el acceso seguro, consistente y fiable a los archivos de usuario. Usted no tendrá que preocuparse de tener el permiso del usuario a menos que el administrador ha desactivado por completo el almacenamiento aislado. Además, si se habilita la itinerancia, los usuarios pueden incluso llevar a sus ajustes con ellos si se utilizan diferentes sistemas en el mismo dominio, bastante resbaladiza eh?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top