2013-12-17 17 views
69

これは私のコードです:Entity Framework 6のマルチ非同期?

var banner = context.Banners.ToListAsync() 
var newsGroup = context.NewsGroups.ToListAsync() 
await Task.WhenAll(banner, newsGroup); 

しかし、私は、コントローラから関数を呼び出したとき。エラーが表示されました

以前の非同期操作が完了する前に、このコンテキストで2番目の操作が開始されました。このコンテキストで別のメソッドを呼び出す前に、非同期操作が完了したことを確認するには、 'await'を使用します。どのインスタンスメンバーもスレッドセーフであるとは限りません。

この問題を解決するのを手伝ってください。

+6

例外はクリスタルクリアで、あなたは何を求めていますか? –

+0

私は2つのタスクを持っています。私は各タスクを実行する場合。それは成功です。しかし、私は上記の私のコードのように実行する場合。それはエラー –

答えて

91

例外は、一度に1つのコンテキストにつき1つの非同期操作しか許可されないことを明確に説明しています。

var banner = await context.Banners.ToListAsync(); 
var newsGroup = await context.NewsGroups.ToListAsync(); 

をそれとも、複数のコンテキストを使用することができます:あなたはIoCコンテナを使用している場合

var banner = context1.Banners.ToListAsync(); 
var newsGroup = context2.NewsGroups.ToListAsync(); 
await Task.WhenAll(banner, newsGroup); 
+0

の仕事です。どうもありがとうございました。 –

+25

ちょうどメモ、あなたが同じエラーをスローされますが、クエリの前にプロパティを取得する待つことでも、クエリのコンテキストを使用するレイジー変数を持っている場合、これを見つけるための痛みだった。 –

+7

@ Pedro.The.Kid:原則として、非同期DBアクセスで遅延ロードを使用しないでください。レイジーローディングは常に同期的なので、追加データのクエリを含めるか別々にする方がはるかに優れています。 –

4

をエラーメッセージが示すように

だから、あなたのいずれかを一度にawaitそのいずれかに持っていますデータプロバイダへのインジェクションでは、ライフサイクルに「一時的」または「PerWebRequest」タイプを使用することを検討してください。例えば

:あなたはたとえば、リポジトリパターンと依存性の注入のためのUnityの使用している場合は、更新/削除/作成してhttps://github.com/castleproject/Windsor/blob/master/docs/lifestyles.md

1

次の2つの以上のコンテキストを使用して次のエラーが発生します。

関係 が異なるObjectContextオブジェクトにアタッチされているため、2つのオブジェクトの間の定義はできません。

これは、PerRequestLifetimeManagerを使用して解決できます。詳細:

C# EF6 make multiple async calls to one context using Unity - Asp.Net Web Api

container.RegisterType<DbContext>(new PerRequestLifetimeManager()); 
container.RegisterType<ISupplierRepository, SupplierRepository>(); 
container.RegisterType<IContactRepository, ContactRepository>();