1

Azure でホストされている MVC 3 アプリをコーディングしました。セッション変数を使用して、実行時間の長いプロセスの 1 つで http 呼び出し間の更新ステータス情報を保存しています。これは、進行状況バーを更新するために使用されます。値はかなり急速に変化する可能性があります。

InProc セッション プロバイダーを使用する場合、これはすべてうまく機能します。ただし、Azure キャッシュ セッション プロバイダーを使用するように変更するたびに、実行時間の長いプロセスからセッション変数が更新されません。

現在、キャッシュ変数を直接使用するように変更していますが、これは今のところ機能しているようです。

キャッシュ内でセッションを使用すると次のメソッドが機能しないのに、InProc は問題ないのはなぜですか?

たとえば、1 つのコントローラー ActionResult でセッション変数を開始するように設定します。

Session["OPERATION_PROGRESS"] = 0;

次に、次のようなセッションのハンドルを取得します

HttpSessionStateBase session = Session;

そしてそれを私の長期実行プロセスに渡します

LongRunningProcess.Go(session);

次に、LongRunningProcess メソッド内から、渡されたセッション オブジェクトを使用してタスクの進行に合わせてセッション変数を更新します。

passedSession["OPERATION_PROGRESS"]=10;

Web クライアントは、進行状況バーを更新するためにセッション変数の値を返す進行状況ページを呼び出します。

4

1 に答える 1

2

最近セッションプロバイダーについて読んだことに基づいて、長時間実行されるリクエストを初期化するリクエストが完了した後、セッションプロバイダーがセッション情報のロックを解放し、効果的に切断することが起こっているのではないかと思います。MSDNから:

要求の最後に、セッション状態の値が変更されている場合、SessionStateModule インスタンスは SessionStateStoreProviderBase.SetAndReleaseItemExclusive メソッドを呼び出して、更新された値をセッション状態ストアに書き込みます。

対話するオブジェクトがまだあります (これが、長時間実行されるプロセスがまだ機能する理由です) が、そのオブジェクトへの変更は永続レイヤーに送信されません (これが、後続の要求がそれらの変更を取得しない理由です)。

同様の状況で私が行ったことは、リクエストの開始時にリクエスト ID を生成し、それをパーティション キーとして Azure テーブルに行を作成し (ただし、任意のストレージを使用できます)、この ID を long に渡すことです。プロセスを実行し、この ID をクライアントに返します。長時間実行されるプロセスは、テーブル内のこの 1 つの行を更新するだけです。進行状況に対する後続のすべてのリクエストは、このリクエスト ID を渡します。これを調べるのは簡単です。テーブルが大きくなりすぎないようにするために、プロセスが完了したことを検出したリクエストで行を削除します。

また、Azure テーブル ストレージを使用する場合のこのシステムの改善点は、ティック単位の現在時刻をパーティション キーとして使用し、別の一意の ID を行キーとして使用することです。このようにして、必要以上に長くテーブルに存在する行を見つけて、それらを一掃することが簡単になります。

于 2012-05-03T01:31:09.613 に答える