質問: EF6とその非同期機能のテストを開始するだけです。私は、スレッドセーフではないことに気づいた時、私は驚いていました。私はちょっとそれがポイントだと思った。 私は自分自身の`Task`ベースの拡張メソッドをすでに何年も持っていましたが、私がEFから待っていたのは、それらをスレッドセーフにすることでした。 少なくとも私のタスクベースの機能は互いに干渉しないように`lock`れています。 EF6はそれほど遠くには行きません。しかし、主な問題は、自分のコードが自分のコードと共有するものです。つまり、非同期クエリを発行してから、完了する前に遅延ロードをトリガーするナビゲーションプロパティ(同じコンテキスト内の事前にロードされた全く別のエンティティ上)にアクセスしようとします。これは、UI、または直接関数外の他のコード、または十数個の他のシナリオによって引き起こされる可能性があります。 私の知る限り。 dbContext内の共有可能な(エンティティ間の)変更可能なリソースは、接続と変更の追跡(キャッシング)だけです。もしそれらを関数にロックすると、スレッドセーフなコンテキストになります。 私たちは2つの段階でそれを行うことすらできます。データベースを照会するために使用される1つの集中機能をロックしたプロバイダを実装できるかどうか。非エンティティ(匿名)オブジェクトを返すか、AsNoTracking()を呼び出すことによって追跡されないクエリは、スレッドセーフであり、別のスレッドが遅延ロードされたオブジェクトを要求している場合でもAsync関数で安全に呼び出すことができます。 スケーラビリティはそれほど悪くなくなりました。スレッドごとに1つのコンテキストを使用する必要があり、Async関数でさえもスキップして並列化を少し待つか、待っている関数がタスクとともに返ってくるとトリガするシステム(wpfのような)。 だから私の質問です。誰もがこのようなプロバイダを実装していますか?それとも誰かが私と一緒に仕事をしたいのですか?
回答: 私はあなたが建築上の問題に直面していると思います。あなたが説明するのは、UIがEFオブジェクトを直接使用するアプリケーションであり、「懸念の分離」のパラダイムを破ります。 私の面では、Modelレイヤー上にカスタムスレッドセーフキャッシュを使用し、Modelレイヤー上ですべての処理を実行します。よく知られているAsyncLockを使用してキャッシュ上にスレッドセーフを実装しました。 DbContextオブジェクト、およびすべてのEF CRUD関連操作の寿命は非常に限られています。各CRUDオペレーションはそれ自身のDbContextをインスタンス化し、モデルオブジェクトをキャッシュに戻し、コンテキストはガベージコレクションされます。私のアプリケーションでは、抽象化レイヤとしてキャッシュを使用し、キャッシュはEFをDB抽象化レイヤとして使用します。 たとえば、オブジェクトの添付プロパティを調べるには、Modelレイヤーにカスタムメソッドを実装します。このメソッドは、オブジェクトIdをパラメータとして取得し、関連オブジェクトのリストをキャッシュに返します。 UIがキャッシュを要求した後、キャッシュはEFを要求し、使用可能になると、キャッシュへの呼び出しはオブジェクトをUIに返します。そのような単純な。 EntityFrameworkはスレッドセーフであるようには設計されていないため、マルチスレッドの方法でそのスレッドを処理する方法はありません。 ( EFスレッドの安全性 ) DbContextに並列アクセスする代わりに、マルチスレッドの方法でアクセスできるModelレイヤーを構築する必要があります。そして、あなたのモデルは複数のDBを並列に呼び出すことができますが、各呼び出しがインスタンス化して、それ自身のDbContextを保持する必要があることに注意してください。各呼び出しの最後に、関連するDbContextを配置する必要があります。 DbContextは実際にはインスタンス化が高速ですが、唯一の欠点はネットワークの待ち時間です。そのため、メモリキャッシュが良いアイデアです。