SO で多くの Q/A を見てきましたが、EF を使用したマルチスレッド化は難しい可能性があると言っています。
私が得たシナリオは、Web API がデータベース内のジョブをキューに入れるというものです。Windows サービス (現時点では実際にはコンソール アプリ) がこれらのジョブを取得し、複数のスレッドで実行して、結果をデータベースに保存します。
現時点ではリポジトリ パターンを使用しており、最初はメイン スレッドのみを使用してデータベースを更新しようとしました。これは、メイン スレッドがデータベースを更新できるよりも (はるかに) 速く作業が行われるため、特に結果が多数 (数万) ある場合には機能しません。
次のアプローチは、スレッドごとのコンテキストに移動することです。これは、コンテナーのライフタイム マネージャーを変更することで非常に簡単に実行できますが、これにより、(おそらく) ワーカー スレッドがジョブ ステータスを「完了」に更新する同時実行性の問題が発生します。ただし、キャッシュされたコピーがまだ「進行中」であるため、メインスレッドは認識しません。
次のアプローチは、リクエストごとのコンテキストを持つことだと思いますが、特に多くのスレッドが並行して実行されている場合、多くのセットアップ/ティアダウンが発生するのではないかと心配しています。いずれにせよ、私はそれを試してみて、それがどれほど良い/悪いかを見ていきます.
最後のオプションが進むべき道であると仮定すると、Unity に同じコンテキストごとの論理リクエストを解決させるにはどうすればよいでしょうか? つまり、私がそうするなら...
Dim UnitOfWork = Container.Resolve(Of IUnitOfWork)
Dim UserRepo = Container.Resolve(Of IUserRepository)
Dim RoleRepo = Container.Resolve(Of IRoleRepository)
''Do Stuff
UnitOfWork.Commit
すべてのオブジェクトが同じコンテキストを使用する必要があります。自分のライフタイム マネージャーを作成し、各グループに固有のものを使用する必要がありますか (新しい Guid など)。
Dim Key = Guid.NewGuid
Dim UnitOfWork = Container.Resolve(Of IUnitOfWork)(New MyLifetimeManager(Key))
Dim UserRepo = Container.Resolve(Of IUserRepository)(New MyLifetimeManager(Key))
またはより良い方法はありますか?