1

目的に合った同様の質問/回答が見つかりませんでした。

コントローラーのいくつかのアクション (MVC 4/EF 5 アプリケーション) には、データベースを更新する機能がありますが、これらの機能はユーザー出力 (選択後に情報を更新する機能) には影響しません。そして、これらの関数を非同期スレッドで送信したいと考えています(ユーザーがレンダリングされたページを取得した後に終了します)。スレッドの終了とページのレンダリングを待ちたくありません。この場合、データベース コンテキストはどうでしょうか。私のコンテキストの有効期間は「リクエストごと」であり、Application_EndRequest で削除されます。

protected virtual void Application_EndRequest()
{
    var entityContext = HttpContext.Current.Items["_Context"] as DbContext;
    if (entityContext != null)
        entityContext.Dispose();
}

スレッドで独自のコンテキストを使用します (ブロックを使用して正しい破棄を行います)。

using (DbContext db = new DbContext())
{
    ....
}

しかし、エンティティをスレッドで DbContext にアタッチしたい場合、いくつかのケースで「同じキーを持つオブジェクトが既に ObjectStateManager に存在します」というエラーが表示されます。AsNoTracking() オプションを使用して読み込みを使用し、新しいスレッドを呼び出す前にメイン コンテキストでエンティティの状態が「切り離されている」ため、奇妙です。それ以外の場合、スレッドでデータベースからの要求エンティティをもう一度試みて、(アタッチするのではなく) 変更しようとすると、「オブジェクトは切り離された状態です」というエラーが数回発生します。 Context の 2 つのインスタンスは 1 つの ObjectStateManager を使用していますか? また、メイン スレッドの Context が破棄される時間に応じてエラーが表示されます。つまり、メインのコンテキストを破棄する前または後に、スレッドでコンテキストを使用します...

この状況で独自のコンテキストを持つ非同期スレッドを操作するにはどうすればよいですか? ありがとう。

4

2 に答える 2

2

ここにはいくつかの問題があります。

1) あるコンテキストに属するオブジェクトまたはそのナビゲーション プロパティを取得し、それらを別のコンテキストで使用しようとすると、見たエラーが発生します。

2) 要求が完了するとすぐに、IIS は自由にリサイクルできAppDomain.ます。これが運用環境で発生すると、ワーカー スレッドは極端な偏見で中止されます。つまり、ワーカー スレッドが何かを実行することにまったく依存することはできません。

高価な作業を延期したい場合は、その作業を別のプロセス (おそらく Windows サービス) に実装された何らかのメッセージ キューに渡す必要があります。

于 2013-03-23T17:47:13.850 に答える
0

私は答えとすべての作品を見つけました。 長時間のバックグラウンド タスクを開始します。Task StartNew() メソッドに、開始するタスクが「長時間実行」であることを示すパラメーターを渡すことができます。これにより、新しいスレッドでタスクを開始するためのヒントがタスク スケジューラに提供されます。

var task = Task.Factory.StartNew(Stuff, TaskCreationOptions.LongRunning);

ありがとう、medkg15

于 2013-03-30T17:44:54.233 に答える