6

ファイルの到着時にイベントを発生させるファイル ウォッチャーを含む Windows サービスがあります。イベントが発生すると、Ninject を使用して、Ninject を介して注入される Entity Framework コンテキストへの参照を持つビジネス レイヤー オブジェクトを作成します。私の Web アプリケーションでは、常にコンテキストに InRequestScope を使用していました。これにより、1 つのリクエスト内で、すべてのビジネス レイヤー オブジェクトが同じ Entity Framework コンテキストで動作します。私の現在の Windows サービス シナリオでは、Entity Framework コンテキスト バインディングを InThreadScope バインディングに切り替えるだけで十分でしょうか?

理論的には、サービス内のイベント ハンドラーがトリガーされると、それは何らかのスレッドで実行されます。別のファイルが同時に到着すると、別のスレッドで実行されます。したがって、両方のイベントが Entity Framework コンテキストを共有することはありません。つまり、Web 上の 2 つの異なる http 要求と同じです。

私を悩ませているのは、Ninject wiki を見ると、これらのスレッドスコープのオブジェクトが破壊されていることです。

.InThreadScope()- タイプの 1 つのインスタンスがスレッドごとに作成されます。
.InRequestScope()- このタイプのインスタンスは Web リクエストごとに 1 つ作成され、リクエストが終了すると破棄されます。

これに基づいて、リクエストが終了したとき(またはその後のある時点)で InRequestScope オブジェクトが破棄される(ガベージコレクション?)ことを理解しています。これは、 InThreadScope オブジェクトがどのように破棄されるかについては何も述べていません。私の例に戻ると、ファイル ウォッチャー イベント ハンドラー メソッドが完了すると、スレッドは離れます (スレッド プールに戻りますか?) 注入された InThreadScope-d オブジェクトはどうなりますか?

編集: InThreadScope() を使用すると、filewatcher のハンドラーが終了したときにオブジェクトが破棄されないことは明らかです。フォルダーに多くのファイルをドロップすることでこれを再現できましたが、最終的に同じスレッド ID を取得したため、以前とまったく同じ Entity Framework コンテキストが得られたため、私のアプリケーションには十分ではありません。この場合、5 分後に到着したファイルは、以前に同じスレッドに割り当てられた古いコンテキストを使用している可能性があります。

4

1 に答える 1

4

スレッド静的なオブジェクトは非常に長い間存在する可能性があります。つまり、ある時点でObjectContext古くなり、古い (キャッシュされた) 値で動作し、見つけにくいバグが発生します。

私は通常ObjectContext、データベース トランザクションを作成するのと同じスコープで を作成します (データベース トランザクションで をラップし、ObjectContextそれらを次々に破棄することもよくあります)。1 つの (Web) リクエストに複数のデータベース トランザクションが含まれる可能性がありますが、通常は、ビジネス ロジックを実行する 1 つの「ビジネス トランザクション」が含まれます。他のトランザクションは、ロギングとして開始できます (ビジネス トランザクションの前、後、場合によってはその間)。ObjectContextビジネス トランザクションが失敗すると、ObjectContextが無効な状態になり、同じ を再利用する操作 (ロギングなど) に影響を与える可能性があるため、要求全体で を再利用すると、混乱が生じる可能性がありObjectContextます。

あなたの Windows サービスでは、File Watcher によって発生するすべてのイベントが新しいビジネス トランザクションをトリガーする可能性があると思います。その場合、ObjectContextイベントごとに新しいものを作成します。

簡単に言うとObjectContext、IoC フレームワークによって管理される有効期間を持つ を注入しません。コードが新しいものを作成して破棄できるようにするファクトリを挿入しますObjectContext。これについての別の質問に答えたところです。その答えで私が提案する解決策を見てください。

幸運を。

于 2010-12-23T13:49:21.823 に答える