Mantenere le impostazioni in sincronia tra l'applicazione forme e il servizio di Windows (o qualsiasi n-tier, in realtà)

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

Domanda

Ho un servizio di Windows che svolge una serie di attività periodiche, e voglio cambiare le impostazioni di questo servizio da un Form app di Windows. Non sono sicuro, però, circa il modo migliore per assicurarsi che il servizio ha le preferenze degli utenti più aggiornati in esso (con quale frequenza eseguire, cosa cartelle da utilizzare per le cose, qualsiasi altra cosa l'utente può specificare). L'utente può modificare le impostazioni in qualsiasi momento, a suo piacimento, e mi piacerebbe il know servizio su di esso quasi immediatamente. Qui ci sono le opzioni che sto di peso:

  1. La forma e il servizio uso condividono la stessa "Impostazioni" oggetto da un terzo progetto, condiviso, e il modulo utilizza un WCF "updatesettings (newSettings)" chiamata a far conoscere al servizio che ci sono stati cambiamenti (o, opzionalmente, una chiamata a aggiornare ogni singola impostazione, anche se questo sembra un sacco su diverse chiamate). Attualmente uso di WCF per i messaggi di base, ma l'oggetto impostazioni possono essere enorme, dal momento che c'è un sacco di altre cose in là
  2. Forma e servizio utilizzare un file di configurazione comune (XML, o le stesse impostazioni oggetto da # 1, ma serializzati su disco). Il modulo appena scrive una nuova copia dell'oggetto dopo che è stato cambiato, e le verifiche di servizio ogni tanto e lo raccoglie se è nuovo, aggiornando la sua copia delle impostazioni
  3. Come il # 2, ma con una chiamata WCF di base che dice che il servizio per andare a prendere le impostazioni. In sostanza, un "on-demand" invece di versione "polling" di # 2.

che conosco meglio è soggettivo, ma io sono interessato a qualsiasi ovvie ragioni pro o condizionata per queste scelte. Dal momento che dovrò salvare le mie impostazioni tra runnings dell'applicazione (riavvii, ecc), dovrò serializzare le impostazioni su disco comunque, quindi sto già appoggiato verso 2 # o # 3. Ho bisogno di un posto sul disco dove posso salvare le impostazioni, ma forse la cartella AppData lavorerò bene, però che consente solo agli amministratori di modificare le impostazioni, dato che sono gli unici che hanno il permesso di scrivere in questa posizione (dove ogni utente, tra cui l'account di servizio, in grado di leggerlo).

Grazie per la vostra comprensione!

È stato utile?

Soluzione

I kinda utilizzare il numero 2.

Ma io sto solo lavorando in .NET 2 con la mia domanda, ma dovrebbe comunque applicare.

Ho una classe impostazioni che uso attraverso i miei 2 programmi. All'interno di questa impostazione I Classe impostazioni di FileSystemWatcher oggetto che esamina il file delle impostazioni.

Se il file di impostazioni viene aggiornato dal l'altra applicazione, il mio attuale ottiene un trigger di evento per indicare che le impostazioni di necessità di ricaricare.

È possibile applicare lo stesso principio anche nelle impostazioni schermo in modo che se il (servizio) altri aggiornamenti delle applicazioni nulla durante la modifica delle impostazioni, che si riflette nel vostro schermo.

Io uso l'AppData (la mia azienda / directory nome dell'applicazione) per memorizzare il file.

L'altra cosa da tenere a mente, è che non ci può essere il blocco sul file mentre viene scritto in modo è possibile utilizzare un nome temporaneo salvare, eliminare, metodo temperatura vecchio rinomina o mettere un po 'di blocco di protezione del file quando leggere dopo l'evento FileWatcher che sono state apportate modifiche.

Io uso questo approccio nel mio FileSystemWatcher prima di procedere,

IPSDependency.FileSystem.WaitForLockOnFile(Me.mFilePath)

il codice per questo è così. (Dopo aver letto questa ora, ci può essere un metodo migliore la mia usando dormire un po 'qui per ridurre botte 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

Altri suggerimenti

Supponendo che tutto è in esecuzione sulla stessa macchina, come su questo:

  1. definire una struttura # c comune che definisce le impostazioni. Tutti i progetti includono questo file .cs. Definire questa classe come un struct con StructLayout di Sequenziale o esplicita in modo che possa essere mappato direttamente in unmanaged condiviso memoria. Ad esempio:

    [StructLayout (LayoutKind.Sequential)] MySharedSettings struct non sicuri {     int IMP1 pubblica;     int Setting2 pubblica;     Setting3 public string;     // aggiungere altri campi qui. }

  2. Usa memoria condivisa di nome (aka: file memory-mapped ). Ciò consente a più processi sullo stesso computer per condividere dati, senza il sovraccarico di Remoting o WCF . La memoria condivisa è estremamente veloce e, a differenza di tubi, offre l'accesso casuale ai dati della memoria condivisa. Il servizio creerebbe la memoria condivisa di nome, e le applicazioni dell'interfaccia utente potrebbe aprire la memoria condivisa. Si dovrebbe utilizzare PInvoke per utilizzare le API di Windows sottostante, ma questo non è un grosso problema.

  3. Le applicazioni dell'interfaccia utente scrivono i MySharedSettings alla memoria condivisa, mentre il servizio legge la memoria condivisa.

  4. Con un nome semaforo e / o nome Mutex per l'accesso di protezione alla memoria condivisa e per segnalare la disponibilità di nuove impostazioni. Il servizio ha un thread in background dedicato che semplicemente eseguire un WaitOne () sul semaforo, e il thread dell'interfaccia utente segnalerà quando nuovi dati vengono scritti.

Di solito i servizi che eseguono un 'operazione di polling' (vale a dire di sincronizzazione file) hanno il tempo di ritardo abbastanza nella loro intervallo di polling che si può altrettanto facilmente rileggere tutte le impostazioni di ciascun ciclo, o anche, se necessario.

Se il servizio è più lungo le linee di un back-end SOA, quindi le modifiche possano influire impostazioni che vengono generalmente utilizzati una sola volta durante la vita di un servizio. Se questo è il vostro tipo di applicazione, quindi l'opzione # 2 si descrive sopra è il più affidabile. Non posso dire che mi interessa molto per l'attuazione di Paolo come polling un file del genere produrrà risultati inaffidabili. Ti consiglio di utilizzare una maniglia attesa di nome a livello globale per segnalare il processo per le modifiche. Sono sicuro che si può trovare un esempio qui su SO. Se non si vuole fare questo allora si potrebbe sondaggio per dell'ultima modifica del file di configurazione cambiando.

Nel complesso la mia preferenza è per il primo approccio con il Registro di sistema per l'archiviazione. Scrivi tutte le impostazioni in valori discreti in un hive del Registro e leggerli on-demand nel vostro servizio. E 'più veloce di quanto si possa pensare e facile da implementare sia sulla parte anteriore e back-end.

Sono d'accordo con la vostra iniziale magra verso # 2 e # 3. In particolare mi piace il 3 # dato che io non sono un fan di polling, ma alla fine penso che la decisione tra 2 # 3 o # sarà guidato dalle esigenze del vostro servizio.

Per quanto riguarda lo stoccaggio delle impostazioni utente mi sento di raccomandare ad esplorare Isolated Storage ( http: //msdn.microsoft.com/en-us/library/3ak841sy.aspx ). Esso fornisce un ottimo meccanismo per l'accesso sicuro, coerente e affidabile per i file degli utenti. Non dovrete preoccuparvi di avere il permesso dell'utente a meno che l'amministratore ha completamente spento Isolato bagagli. Inoltre se si attiva in roaming, gli utenti possono anche prendere le loro impostazioni con loro se essi utilizzano sistemi diversi nello stesso dominio, piuttosto liscia eh?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top