我有一个返回一些 JSON 的控制器方法。它将一个集合拉出会话,从集合中取出第一个项目,然后将其从集合中删除。如果方法开始时的计数为 1,则现在为 0。
如果我再次以相同的方法从会话中检索集合以检查集合计数是否小于一个,则它是。
到目前为止很简单的东西。
在随后的请求中,集合再次从会话中拉出,但不是预期的计数为 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 键入)并得到相同的结果。其他请求没有更新值。就像我的配置中禁用了同步一样。
我也在两台电脑上试过这段代码,结果一样。