5

HttpContext.Current.Items内に保存する EF4 オブジェクト コンテキストの問題に直面しており、リクエストが完全に処理されたらすぐに破棄したいと考えています。

Aplication_EndRequest イベントで、 HttpContext.Current.ItemsコレクションからアクティブなObjectContextを検索する RepositoryContext の Terminate() メソッドを呼び出し、その接続でClose()を呼び出し、それでDispose()を呼び出します。

問題は、自分のページの 1 つで奇妙な動作をすることがあるということです。場合によっては、次のようなエラーが表示されます。

ObjectContext インスタンスは破棄され、接続を必要とする操作には使用できなくなりました

ページリクエストが終了したら Application_EndRequest イベントを呼び出すだけでなく、画像リクエストなども呼び出すため、おそらくこれが発生する可能性があると考えました。もちろんHTTPリクエスト間で共有されないコレクションHttpContext.Current.Itemsですべてが作成されるため、発生しません。

また、調査によると、一部の db リクエストの遅延読み込みが原因である可能性がありますが、コードの他の場所で Dispose を呼び出さないため (確認済み)、EndRequest の Dispose() を呼び出す必要があるため、ここではそうではありません。すべてが終了したときにのみ呼び出されますよね?

これを引き起こす原因についてのアイデアはありますか?どうすればテストできますか?あなたは何を提案しますか?

ありがとう!

4

2 に答える 2

1

これは、Dispose() が ObjectContext で既に呼び出されたことを意味します。これが発生する理由にはさまざまな理由がありますが、突き詰めると、何かが Application_EndRequest の前に Dispose() を呼び出しているという事実に帰着します。すべてのソースがなければ、その理由を正確に伝えることは不可能です。

あなたは推奨事項を求めているので、最初に HttpContext から ObjectContext を取り出します。データベース接続は短時間だけ存続し、特定のタスクを実行する必要があります。寿命が短い場合は、Dispose() を自動的に呼び出す using ステートメント内に ObjectContext を配置できます。

于 2012-06-13T17:56:02.643 に答える
1

現在の ObjectContext を提供するクラスがあると仮定すると、プログラマーがブログなどの例に従って、次のように書いた可能性があります。

using(var context = ContextProvider.GetCurrentContext()){
    ...
}

リクエストが終了する前に ObjectContext を破棄しました。

ObjectContext が破棄されている場所をテストする場合は、次のようにします。

ObjectContext の実装で、Dispose メソッドを次のように変更します。

public override void Dispose() {
    throw new InvalidOpearationException("Gotcha!");
}

public void ActuallyDisposePlease() {
    base.Dispose();
}

そして Application_EndRequest で、ActualDisposePlease() メソッドを呼び出します。

もちろん、これはテスト/デバッグ/診断の観点からのものであり、決して本番環境に影響を与えるべきではありません。

于 2012-06-13T18:08:41.443 に答える