フォームアプリケーションとWindowsサービス(または任意のnティア、実際に)間で設定を同期させます

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

質問

多くの定期的なアクティビティを実行するWindowsサービスがあり、Windowsフォームアプリからこのサービスの設定を変更したいと考えています。ただし、サービスが最も更新されたユーザー設定があることを確認するための最良の方法についてはわかりません(実行する頻度、物事に使用するフォルダー、ユーザーが指定できるものは何でも)。ユーザーはいつでもいつでも設定を変更できます。また、サービスについてほぼすぐに知りたいと思います。これが私が計量しているオプションです:

  1. フォームとサービスの共有は、3番目の共有プロジェクトから同じ「設定」オブジェクトを使用し、フォームはWCF "updatesettings(Newsettings)" Callを使用して、サービスに変更があったことを知らせます(または、オプションでは、個々の設定を更新しますが、これは異なる呼び出しよりも多くのように思えます)。私は現在、基本メッセージにWCFを使用していますが、そこには他にもたくさんのものがあるので、設定オブジェクトは巨大になる可能性があります
  2. フォームとサービスは、共通の構成ファイル(XML、または#1から同じ設定オブジェクトですが、ディスクにシリアル化されています)を使用します。フォームは、オブジェクトが変更された後に新しいコピーを書き留め、サービスは頻繁にチェックし、新しい場合にそれを取り上げ、設定のコピーを更新します
  3. #2と同じですが、基本的なWCFコールでは、サービスに設定を取得するように指示します。基本的に、#2の「ポーリング」バージョンではなく「オンデマンド」。

私はBestが主観的であることを知っていますが、これらの選択の明白なプロまたはConの理由に興味があります。アプリケーションの実行(再起動など)の間に設定を保存する必要があるため、とにかく設定をディスクにシリアル化する必要があるため、すでに#2または#3に傾いています。設定を保存できるディスク上の場所が必要ですが、AppDataフォルダーは正常に動作するかもしれませんが、この場所に書き込む許可を持っている唯一の管理者は、管理者が設定を変更できるようにするだけです。 (サービスアカウントを含むすべてのユーザーが読むことができます)。

洞察をありがとう!

役に立ちましたか?

解決

私はあなたの番号2を使っています。

しかし、私はアプリケーションで.NET 2でのみ作業していますが、それでも適用する必要があります。

2つのプログラムで使用する設定クラスがあります。この設定の内部クラスIセットアップa FilesystemWatcher 設定ファイルを見るオブジェクト。

設定ファイルが他のアプリケーションによって更新された場合、私の現在の電流は、設定がリロードする必要があることを示すイベントトリガーを取得します。

また、設定画面に同じ原則を適用して、他のアプリケーションが設定編集中に何かを更新する場合、画面に反映されるようにすることもできます。

AppData(私の会社/アプリケーション名ディレクトリ)を使用してファイルを保存します。

もう1つのことを心に留めておくべきことは、ファイルが書かれている間にファイルにロックすることができるため、TEMP名の保存、古いものを削除し、一時メソッドの名前を変更するか、後に読み取るときにファイルに保護ロックを置くことができるということです。 FileWatcherイベントが変更されました。

私は自分の中でこのアプローチを使用しています FilesystemWatcher 進む前に

IPSDependency.FileSystem.WaitForLockOnFile(Me.mFilePath)

そのためのコードはこのようなものです。 (今これを読んで、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

他のヒント

すべてが同じマシンで実行されていると仮定すると、これはどうですか:

  1. 設定を定義する共通のC#構造を定義します。すべてのプロジェクトには、この.csファイルが含まれます。このクラスをaとして定義します struct とともに structlayout一連の また 明示的 そのため、管理されていない共有メモリに直接マッピングできます。例えば:

    structlayout(layoutkind.sequential)] unsafe struct mysharedsettings {public int sitent1; public int sitent2; public string sitesd3; //ここにフィールドを追加します。 }

  2. 使用する 共有メモリと名付けられました (別名: メモリマップされたファイル)。これにより、同じコンピューター上の複数のプロセスがデータを共有できます。 リモート また WCF. 。共有メモリは非常に高速であり、パイプとは異なり、共有メモリデータへのランダムアクセスを提供します。このサービスは、指定された共有メモリを作成し、UIアプリケーションは共有メモリを開きます。基礎となるWindows APIを使用するにはPinvokeを使用する必要がありますが、これは大したことではありません。

  3. UIアプリケーションは、MysharedSettingsを共有メモリに書き込み、サービスは共有メモリを読み取ります。

  4. 使う セマフォと名付けられました および/または 名前付きMutex 共有メモリへのアクセスを保護し、新しい設定の可用性を通知するため。このサービスには、セマフォでwaitone()を実行する単純に実行される専用の背景スレッドがあり、UIスレッドは新しいデータが記述されると信号を送信します。

通常、「ポーリング操作」(つまり同期ファイル)を実行するサービスは、ポーリング間隔で十分な遅延時間を持ち、各ループ、または必要に応じてすべての設定を簡単に読み直すことができます。

サービスがSOAバックエンドのラインに沿っている場合、変更は通常、サービスの寿命の間に1回しか使用されていない設定に影響を与える可能性があります。これがアプリケーションのタイプである場合、上記で説明するオプション#2が最も信頼できます。そのようなファイルを投票することで信頼できない結果が得られるため、ポールの実装にはあまり気にしているとは言えません。グローバルに名前が付けられた待機ハンドルを使用して、プロセスを変更することをお勧めします。ここで例を見つけることができると確信しています。それをやりたくない場合は、構成ファイルの永久に変更された時間の変更を投票することができます。

全体的に私の好みは、レジストリをストレージ用に使用する最初のアプローチに対するものです。すべての設定をレジストリハイブに個別の値で記述し、サービスのオンデマンドでそれらを読み取ります。考えているよりも速く、フロントエンドとバックエンドの両方で簡単に実装できます。

私はあなたの最初のリーンに#2と#3に向かって同意する必要があります。私は投票のファンではないので、私は特に#3が好きですが、最終的には#2または#3の間の決定はあなたのサービスの要件によって推進されると思います。

ユーザー設定の保存については、孤立したストレージを探索することをお勧めします( http://msdn.microsoft.com/en-us/library/3ak841sy.aspx )。これは、ユーザーファイルへの安全で一貫した、信頼できるアクセスのための優れたメカニズムを提供します。管理者が完全に孤立したストレージをオフにしていない限り、ユーザーの許可を得ることを心配する必要はありません。さらに、ローミングを有効にする場合、ユーザーは同じドメインで異なるシステムを利用している場合、自分の設定を取得することさえできます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top