2017-12-04 10 views
0

タスクを使用してメールをバックグラウンドで送信しています。 PDF(添付ファイルとしてメールに含まれています)が生成されています(GeneratePdf())。私は、例外以下の取得: enter image description hereタスクからのEF:System.InvalidOperationException:リーダーが閉じた

EDIT は以下dbContextがロードされたコード(Startup.cs、メソッドConfigureServices)である:以下

enter image description here

GetRegistrationOfChildを呼び出すコードです。その後、そのコンストラクタのDIで解決されました。

services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

+0

'dbContext'はどこから来たのですか? – ViRuSTriNiTy

+0

実際にコードがどこから呼び出されたのかはわかりませんが、中央の欠けている部分がここにあります。あなたがデータを取得する機会を得る前に、文脈を閉鎖/破棄していますか? – DavidG

+0

説明を編集しました。 'dbContext'はコンストラクタ内のDIによって処理されます。私は文脈を閉じたり、処分したりするつもりはない。 – user2810895

答えて

2

問題の多くは、実際には、ここにあります。あなたの中心的な問題は、SendRegisterConfirmationAsyncメソッドの中にある可能性があります。ただし、そのメソッドのコードは提供していません。私が推測しなければならないのであれば、エラーメッセージに基づいてスレッドセーフではない方法でusingステートメントを使用しています。

ただし、非同期処理が不適切であることもあります。あなたは、同期メソッドから非同期メソッドを呼び出しています。 SendEmailがvoidを返すので、asyncメソッドの戻り値を飲み込んでいるか、または非同期メソッドがasync void(これはかなりではありません。)です。どちらの場合でも、非同期メソッドの結果を待っているわけではないので、残りのコードは潜在的に依存関係を取っています。たとえば、DbContextのようなものはリクエストスコープです。その非同期メソッドがDbContextを利用していて応答が送信される前に終了していない場合は、コンテキストがそのすぐ下に配置され、例外が発生します。 asyncを使用している場合は、にはが必要です。

さらに、実際には、Webアプリケーションのコンテキストに真のバックグラウンドタスクはありません。 Task.Runは、要求が処理されている同じプールから別のスレッドを単にプルします。あなたは1つのスレッドが戻ることを許可することができますが、あなたはまだ別のスレッドに座っているので、最良の場合のシナリオは、あなた自身を何も買っていないということです。最悪のシナリオは、サーバーのスループットを効果的に半分にして、拡張性を失ったことです。

バックグラウンドで何かしたい場合は、プロセスのバックグラウンドに、つまりウェブアプリケーションのコンテキストの外にオフロードします。 HangfireまたはRevaleeのようなものを使用できます。

関連する問題