バックグラウンド:
NetTCP バインディングを使用して Windows サービス内で WCF サービスをホストするシステムがあります。コレクションに新しいサービスを追加するには、<system.serviceModel -> services /> 内に標準の WCF 構成エントリを追加し、サービスを初期化する必要があるホスティング フレームワークに通知するカスタム構成セクション内に行を追加します。各サービスは、独自のバックグラウンド スレッドと AppDomain インスタンスで初期化され、すべてが分離された状態に保たれます。
サービスの初期化方法の例を次に示します。
Host
- ServerManager
- ServiceManager
- BaseServerHost
ServerManager インスタンスには、標準の WCF 実装 (ServiceHost.Open/Close など) がある単一のサービス インスタンスにそれぞれ関連付けられている ServiceManagers のコレクションがあります。ServiceManager インスタンスは、BaseServerHost 基本クラス (抽象) を使用してサービスのインスタンスを (構成に基づいて - 標準のアセンブリ/型定義を持って) インスタンス化します。フレームワークがそれを使用できるようにするには、すべてのサービスがこれを継承する必要があります。初期化プロセスの一部として、BaseServerHost はいくつかのイベントを公開します。具体的には、所有する ServiceManager がアタッチする UnhandledException イベントです。(この部分は、以下の質問に関連して重要です。)
このプロセス全体は、私たちにとって非常にうまく機能します (1 つのインスタンスが 63 のサービスを実行しています)。なぜなら、WCF について何も知らない人を連れてきて、サービスを非常に迅速に作成できるからです。
質問:
私が遭遇した問題は、バックグラウンド スレッドに関するものです。エンドポイントで公開されているメソッドの大部分は、他のシステムへのメッセージの送信など、標準の挿入/更新/削除メソッド呼び出しの後にかなりの量のアクティビティを実行します。パフォーマンスを維持するために (フロントエンドは Web ベースです)、最初の挿入/更新/削除メソッドに処理を任せてから、バックグラウンド スレッドを起動して、エンド ユーザーが待つ必要のないすべてのものを処理します。完了します。このオプションは、そのバックグラウンド スレッドの何かが処理されず、Windows サービス全体がダウンするまでうまく機能します。
私のすべての調査に基づいて、グローバルな try/catch を実装する方法がないことがわかりました (バックグラウンド クラッシュの 1.1 処理を有効にするハッキングされた構成を使用することを除く)。 . それはさておき、私が見つけたのは、WCFホスティングのエンドポイント側で、各呼び出しで独自のスレッドにあるように見え、そのスレッドが「親」と通信するのは悪夢でした。サービスの観点から見たレイアウトは次のとおりです。
Endpoint (svc - inherits from BaseServerHost, mentioned above)
- Business Layer
- Data Layer
ビジネス レイヤーのバックグラウンド スレッドで例外をキャッチすると、それを Endpoint インスタンス (BaseServerHost から継承) にバブルアップし、この特定のサービス (インスタンス化した所有 ServiceManager によってアタッチされた) に対して BaseServerHost の UnhandledException イベントを発生させようとします。それ)。残念ながら、イベント ハンドラーはもう存在しないため、何もしません。これを機能させるために多くのことを試みましたが、これまでのところ、私の努力はすべて無駄になっています。
完全なモデル (以下に示す) を見ると、ビジネス層にその親エンドポイント (これは機能します) を認識させる必要があり、エンドポイントは実行中の BaseServerHost インスタンスを認識し、それをホストしている ServiceManager を認識する必要があります。エラーは、標準のログ記録手順で使用するために、これまで泡立てることができます。
Host
- ServerManager
- ServiceManager <=====================
- BaseServerHost ||
- Endpoint (svc) ||
- Business Layer <======
- Data Layer
私は運が悪い静的クラスを試してみましたが、ServerManager を静的にし、ServiceManagers の以前の内部コレクションを公開することさえしましたが (シャットダウンできるように)、そのコレクションも常に空または null です。
これを機能させることについての考えはありますか?
編集:もう少し掘り下げた後、私がこれをどのように機能させるかを正確に示す例を見つけました。標準の ASP.NET Web サイトでは、任意のページ/ハンドラーなどで、HttpContext.Current プロパティを使用して、その要求の現在のコンテキストにアクセスできます。これはまさに、そのサービスの所有 ServiceManager を返す「ServiceManager.Current」でこれを機能させたい方法です。おそらくそれが役立ちますか?