JSON を返すコントローラー メソッドがあります。コレクションをセッションから引き出し、コレクションから最初のアイテムを取得してから、コレクションから削除します。メソッドの開始時のカウントが 1 だった場合、現在は 0 です。
同じメソッドでセッションからコレクションを再度取得して、コレクション数が1未満かどうかを確認すると、そうです。
ここまでは簡単なこと。
後続のリクエストで、コレクションはセッションから再度プルされますが、カウントが予想どおり 0 ではなく 1 になります。以前に削除されたアイテムは削除されていません! どうしてこれなの?
ただし、十分な数のリクエストが行われた場合、カウントは実際にはゼロになります。セッション オブジェクトがすべてのスレッド間で同期するのに 30 秒ほどかかるようです。
これは本当にそうでしょうか?MVC4 (以前のバージョンでもある可能性がありますか?) には、奇妙なセッション同期の問題がありますか?
デフォルトの InProc セッション プロバイダーと設定を使用しています。
ログは次のとおりです。
Thread Level Logger Message
23 DEBUG ProjectMvc.Controllers.RpcController Pre-processing - Tasks.Count: 1
23 DEBUG ProjectMvc.Controllers.RpcController Post processing - SessionID: asaq1v5afu0pwz13at4a24hl
23 DEBUG ProjectMvc.Controllers.RpcController Post processing - Tasks.Count: 0
16 DEBUG ProjectMvc.Controllers.RpcController Pre-processing - Tasks.Count: 1
16 DEBUG ProjectMvc.Controllers.RpcController Post processing - SessionID: asaq1v5afu0pwz13at4a24hl
16 DEBUG ProjectMvc.Controllers.RpcController Post processing - Tasks.Count: 0
23 DEBUG ProjectMvc.Controllers.RpcController Pre-processing - Tasks.Count: 1
23 DEBUG ProjectMvc.Controllers.RpcController Post processing - SessionID: asaq1v5afu0pwz13at4a24hl
23 DEBUG ProjectMvc.Controllers.RpcController Post processing - Tasks.Count: 0
24 DEBUG ProjectMvc.Controllers.RpcController Pre-processing - Tasks.Count: 1
24 DEBUG ProjectMvc.Controllers.RpcController Post processing - SessionID: asaq1v5afu0pwz13at4a24hl
24 DEBUG ProjectMvc.Controllers.RpcController Post processing - Tasks.Count: 0
9 DEBUG ProjectMvc.Controllers.RpcController Pre-processing - Tasks.Count: 1
9 DEBUG ProjectMvc.Controllers.RpcController Post processing - SessionID: asaq1v5afu0pwz13at4a24hl
9 DEBUG ProjectMvc.Controllers.RpcController Post processing - Tasks.Count: 0
14 DEBUG ProjectMvc.Controllers.RpcController Pre-processing - Tasks.Count: 1
14 DEBUG ProjectMvc.Controllers.RpcController Post processing - SessionID: asaq1v5afu0pwz13at4a24hl
14 DEBUG ProjectMvc.Controllers.RpcController Post processing - Tasks.Count: 0
セッション中のコレクションが他のリクエストに対して更新されていない理由がわからない場合は、それを回避してデータベースに保存する必要があります。
コードは次のとおりです。
public ActionResult GetCoordinatesTask()
{
var user = Session["User"] as IUser;
if (user == null)
{
Logger.LogError(this, "No user in session!");
return Json(null, JsonRequestBehavior.AllowGet);
}
if (user.PhotoGeocodingTasks == null || user.PhotoGeocodingTasks.Count == 0)
return Json(null, JsonRequestBehavior.AllowGet);
lock (user.PhotoGeocodingTasks)
{
Logger.LogDebug(this, "Pre-processing - PhotoGeocodingTasks.Count" + user.PhotoGeocodingTasks.Count);
var task = user.PhotoGeocodingTasks[0];
if (!user.PhotoGeocodingTasks.Remove(task))
Logger.LogError(this, "Could not remove geocoding task after picking it up!");
var encodedTask = new Dictionary<string, string>
{
{"photoid", task.PhotoId.ToString(CultureInfo.InvariantCulture)},
{"latlong", task.Latitude + "," + task.Longitide}
};
Logger.LogDebug(this, "Post processing - SessionID: " + Session.SessionID);
Logger.LogDebug(this, "Post processing - PhotoGeocodingTasks.Count" + user.PhotoGeocodingTasks.Count);
return Json(encodedTask, JsonRequestBehavior.AllowGet);
}
}
編集
セッションのweb.configにあるものは次のとおりです。
<sessionState mode="InProc" customProvider="DefaultSessionProvider">
<providers>
<add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</providers>
</sessionState>
編集 2
また、このタスク データを HttpRuntime.Cache にも保存しようとしましたが (ユーザー ID に対してキーを設定)、同じ結果が得られました。他のリクエストの更新された値はありません。私の構成で同期が無効になっているようです。
このコードを2台のコンピューターでも試しましたが、同じ結果です。