更新-2014年6月
AutoFacの使用に関するベストプラクティスが進み、MVCが変更されたため、この回答を更新しました。変更点は、AutoFacのベストプラクティスは、.InstancePerLifetimeScope()サフィックスを使用して、アクセスの存続期間全体にわたって持続する必要のあるインスタンスを定義することです(MVCの場合はHttpRequest)。例については、以下を参照してください。
builder.RegisterType<MyDbContext>().As<IMyDbContext>().InstancePerLifetimeScope();
これにより、タスク内で作成する新しいライフタイムスコープの名前を指定する必要がなくなります(以下の更新された元の回答を参照してください)。
MVCでのタスクに関するその他の注意事項として、役立つと思われるものがいくつかあります。
- 新しいasync/awaitを使用している場合は、新しいライフタイムスコープは必要ありません。Aysnc / awaitは現在のコンテキストを維持し、単にスレッドを解放して、負荷がかかった状態でWebのパフォーマンスを向上させます。
- 本当にバックグラウンドで何かを実行したい場合は、警告が表示されます-いくつかの問題があります。非同期の専門家であるStephenClearyによるこの役立つブログ投稿を読むことをお勧めします。
- 本当に便利な組み合わせの1つは、SignalRをMVCと組み合わせて使用して、進行状況を報告し、ユーザーがキャンセルできるようにすることです。これは私にとってうまくいきました。
元の投稿ですが、更新されています(注:上記のようにライフタイムスコープインスタンスを登録する必要があります)
GoogleAutofacグループを介して依存関係のある非同期タスクを処理する方法を見つけました。MVCレベルのコンテナーにアクセスして、解決の新しい有効期間スコープを作成できることがわかりました。それを行うにはいくつかの方法がありますが、Alex Meyer-Gleaves(専門家)によるこの回答が答えを提供します。Alexは、スコープが異なるタスクを実行するために、以下のコードを提案しています。
public void Run<T>(Action<T> action)
{
Task.Factory.StartNew(delegate
{
using (var container = AutofacDependencyResolver.Current
.ApplicationContainer.BeginLifetimeScope())
{
var service = container.Resolve<T>();
action(service);
}
});
}
Alexの投稿の主題に関するより詳細なブログ投稿へのリンクがあります。これも非常に便利です。