Halten Sie Einstellungen synchron zwischen Formularanwendung und Windows-Dienst (oder einem n-tiere, wirklich)

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

Frage

Ich habe einen Windows-Dienst, führt eine Reihe von regelmäßigen Aktivitäten, und ich möchte die Einstellungen dieses Dienstes von einem Windows Forms app ändern. Ich bin sicher, aber nicht, um die beste Art und Weise sicher, dass der Dienst zu machen hat die aktuellsten Benutzereinstellungen in ihm (wie oft ausgeführt werden, was für Dinge zu verwenden, um Ordner, was sonst der Benutzer angeben kann). Der Benutzer kann Einstellungen jederzeit ändern, nach Belieben, und ich würde den Service-Know darüber fast sofort mag. Hier sind die Optionen, die ich bin mit einem Gewicht:

  1. Die Form und Service Mitbenützung das gleiche „Einstellungen“ Objekt von einem dritten, gemeinsamen Projekt und das Formular verwendet einen WCF „UpdateSettings (newSettings)“ Anruf den Dienst wissen zu lassen, dass es Änderungen war (oder optional a rufen jede einzelne Einstellung zu aktualisieren, wenn dies wie eine Menge über verschiedene Anrufe scheint). Ich WCF zur Zeit für grundlegende Nachrichten verwenden, aber die Einstellungen Objekt kann sehr groß sein, da es eine Menge anderer Dinge ist da drin
  2. Form und Service verwenden eine gemeinsame Konfigurationsdatei (XML, oder die gleichen Einstellungen Objekt von # 1, aber auf der Festplatte serialisiert). Das Formular schreibt gerade eine neue Kopie des Objekts, nachdem es geändert wurde, und die Service-Prüfungen es jeder so oft und nimmt, wenn es neu, seine Kopie der Einstellungen zu aktualisieren
  3. Wie # 2, aber mit einem grundlegenden WCF Aufruf, dass der Dienst sagt die Einstellungen zu gehen zu bekommen. Im Wesentlichen eines "on-demand" statt "Polling" Version # 2.

Ich weiß am besten ist subjektiv, aber ich bin in offensichtliche pro oder contra Gründe für diese Entscheidungen interessiert. Da muss ich werde meine Einstellungen zwischen runnings der Anwendung speichern (Neustarts, etc.), werde ich auf jeden Fall die Einstellungen auf die Festplatte serialisiert werden müssen, so bin Neigung ich schon auf # 2 oder # 3. Ich werde einen Platz auf der Festplatte benötigen, wo ich die Einstellungen speichern kann, aber vielleicht die AppData-Ordner funktionieren in Ordnung, obwohl das nur Administratoren erlaubt, die Einstellungen zu ändern, da sie die einzigen sind, die Erlaubnis zu schreiben, um diesen Ort hat (wo jeder Benutzer, einschließlich dem Dienstkontos, kann es lesen).

Vielen Dank für Ihre Einsicht!

War es hilfreich?

Lösung

ich irgendwie verwenden Ihre Nummer 2.

Aber ich arbeite nur in .NET 2 mit meiner Anwendung, aber es sollte noch gelten.

ich eine Einstellungs Klasse haben, dass ich über meine 2-Programme verwenden. Innerhalb dieser Einstellungen Klasse-I-Setup ein Filesystemwatcher Objekt, Blicke auf die Einstellungsdatei.

Wenn die Einstellungsdatei von der anderen Anwendung aktualisiert wird, mein Strom bekommt ein Ereignis auslösen, um anzuzeigen, dass die Einstellungen neu geladen werden müssen.

Sie können auch das gleiche Prinzip in Ihren Einstellungen gelten Bildschirm, so dass, wenn das (Service) anderes Anwendungs-Updates etwas während der Einstellungen zu bearbeiten, die in Ihrem Bildschirm reflektiert wird.

Ich verwende den AppData (meine Firma / Anwendungsname Verzeichnis), um die Datei zu speichern.

Die andere Sache zu bedenken ist, dass es auf der Datei sperrt, während es geschrieben wird, so dass Sie entweder ein temporärer Name löscht alt zu speichern, verwenden können, Umbenennungs Temp-Methode oder setzen einige Schutzverriegelung auf der Datei, wenn Lesen nach den Penguin Computing-Ereignis ausgelöst wird, dass Änderungen vorgenommen wurden.

ich diesen Ansatz in meinem Filesystemwatcher bevor Sie fortfahren

IPSDependency.FileSystem.WaitForLockOnFile(Me.mFilePath)

Der Code für das ist so. (Bei der Lektüre dieses jetzt, kann es eine bessere seine Methode meines etwas Schlaf mit in hier CPU Dreschen reduzieren)

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

Andere Tipps

Unter der Annahme, dass alles auf der gleichen Maschine ausgeführt wird, wie etwa diese:

  1. definieren eine gemeinsame c # Struktur, die die Einstellungen definiert. Alle Projekte sind diese CS-Datei. Definieren Sie diese Klasse als struct mit einem StructLayout Sequential oder Explicit , so dass es direkt in den nicht verwalteten geteilt abgebildet werden können Erinnerung. Zum Beispiel:

    [StructLayout (LayoutKind.Sequential)] unsicher struct MySharedSettings { public int setting1; public int Einst.2; public string Setting3; // mehr Felder hier hinzufügen. }

  2. Mit namens Shared Memory (aka: Memory-Mapped-Dateien ). Auf diese Weise können mehrere Prozesse auf demselben Computer zu teilen Daten, ohne den Overhead von Remoting oder WCF . Gemeinsam genutzter Speicher ist extrem schnell und, im Gegensatz zu Rohren, bietet Direktzugriff auf die gemeinsam genutzten Speicherdaten. Der Dienst würde den Namen gemeinsam genutzten Speicher erstellen, und die UI-Anwendungen würden den gemeinsamen Speicher öffnen. Sie würden pinvoke verwenden, haben die zugrunde liegenden Windows-APIs zu verwenden, aber das ist keine große Sache.

  3. Die UI-Anwendungen schreiben, die MySharedSettings auf den gemeinsam genutzten Speicher, während der Dienst den gemeinsam genutzten Speicher liest.

  4. Verwenden Sie ein Namen Semaphore und / oder genannt Mutex zu schützen Zugriff auf den gemeinsam genutzten Speicher und die Verfügbarkeit von neuen Einstellungen zu signalisieren. Der Dienst hat einen eigenen Thread Hintergrund, dass einfach eine WaitOne ausführen () auf der Semaphore und der UI-Thread signalisiert, wenn neue Daten geschrieben werden.

In der Regel Dienstleistungen, die einen ‚Abfragevorgang‘ (das heißt Sync-Dateien) haben genug Verzögerungszeit in ihrem Pollintervall führen, dass Sie genauso einfach wieder lesen alle Einstellungen jede Schleife oder sogar je nach Bedarf.

Wenn Ihr Dienst mehr entlang der Linien eines SOA-Back-End ist, dann können die Änderungen Einstellungen beeinflussen, die im Allgemeinen nur einmal während eines Dienstes Lebensdauer verwendet werden. Ist dies Ihre Art der Anwendung, dann ist die Option # 2 Sie oben beschreiben ist das zuverlässigste. Ich kann ich viel für Paul-Implementierung als Polling nicht sagen pflegen eine Datei wie das wird unzuverlässige Ergebnisse liefern. Ich würde empfehlen, ein global namens Waithandle mit Ihrem Prozess für Änderungen zu signalisieren. Ich bin sicher, können Sie ein Beispiel hier auf SO finden. Wenn Sie nicht das tun wollen, dann können Sie abfragen, für die Zeit verändert geändert zuletzt der Konfigurationsdatei.

Insgesamt meine Präferenz ist für den ersten Ansatz der Registrierung für die Speicherung verwenden. Schreiben Sie alle Ihre Einstellungen in diskreten Werten in einer Registrierungsstruktur und lesen Sie sie bei Bedarf in Ihren Diensten. Es ist schneller als Sie vielleicht denken und einfach auf Front zu implementieren und Back-End.

Ich habe mit Ihrer ersten mageren Richtung # 2 und # 3 zu vereinbaren. Besonders gefällt mir die # 3, da ich kein Fan von Polling bin aber letztendlich denke ich, die Entscheidung zwischen # 2 oder # 3 wird von den Anforderungen Ihres Service betrieben werden.

Wie für die Speicherung von Benutzereinstellungen würde ich Isolated Storage empfehlen die Erkundung ( http: //msdn.microsoft.com/en-us/library/3ak841sy.aspx ). Es bietet einen hervorragenden Mechanismus für sicheren, konsistenten und zuverlässigen Zugriff auf den Benutzerdateien. Sie werden nicht über Benutzer, die Erlaubnis zu kümmern, es sei denn, der Administrator vollständig aus isolierten Speicher geworden ist. Plus, wenn Sie ermöglichen Roaming können Benutzer nehmen sogar ihre Einstellungen mit ihnen, wenn sie eh verschiedene Systeme auf der gleichen Domain, ziemlich glatt nutzen?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top