SNIReadSyncOverAsync と WaitForSingleObject が EF のパフォーマンスをブロックしていますか? 質問する

SNIReadSyncOverAsync と WaitForSingleObject が EF のパフォーマンスをブロックしていますか? 質問する

私は、EF を使用して SQL DB から読み取る WCF サービスでプロファイリングを行っています(System.Data.Entities)。サービスにアクセスする複数の並列クライアントを起動すると、CPU がすべて 100% になり、パフォーマンスが全体的に低下し、すべてが遅くなります。

これを並行性プロファイラーでプロファイリングしたところ、時間の 85% が同期に費やされ、実際のコード実行は約 4% のみであることがわかりました。スタック トレースを詳しく調べると、同期のほとんどは の への呼び出しによるものであるようですWaitForSingleObjectSystem.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsyncスタックは、呼び出しがネイティブ メソッド ラッパーに行き、その後 で終了することを示していますkernel32.dll!_WaitForSingleObject

これまでにこれを経験した人はいますか? これについて何か対処法はありますか? これに異常な負荷をかけているわけではなく、並列クライアントが約 20 個あるだけで、すべて読み取り専用なので、スレッドが同期しようとすること自体が驚きです。

もう 1 週間、この問題と格闘していますが、説明できません。どなたか助けていただければ幸いです。

ベストアンサー1

これを、問題を再現する小さなコード サンプルにまとめることはできますか? 使用している EF のバージョンは何ですか?

これまでに提供された情報に基づいたいくつかの観察結果を以下に示します。

EF 非同期

EF6未満のものはいつも同期。EF 6では、代わりに非同期メソッドただし、WCF サービスでも非同期パターンが使用されない限り、これを行わないでください。

WCF 非同期

非同期実装のWCFサービスを書くことができます。このドキュメント詳細については。

使用する場合は1つ上記の方法のどちらか一方だけを使用すると、コードは非同期にならず、不要な同期オーバーヘッドが発生します。特に、Task.Run()または同等の方法は、スループットを実際に向上させることなく、単に作業を別のスレッドに移動するだけなので、使用しないでください。

初期化

最後に、別の無関係なアイデアです。問題は EF の初期化に関連している可能性がありますか? EF がモデルのメタデータを構築するとき、接続文字列ごとにこれを 1 回実行します。複数のスレッドが同じモデルを使用しようとし、そのモデルがまだ初期化されていない場合、初期化が完了するまですべてのスレッドがブロックされます。これが問題かどうかを確認するには、サービスに 1 回呼び出して完了させます。次に、20 の並列要求を送信します。それでも CPU が最大限に使用されますか?

おすすめ記事