我有一个返回一些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)并获得相同的结果。没有其他请求的更新值。就像在我的配置中禁用同步一样。
我在两台计算机上也尝试过这个代码,结果相同。
答案 0 :(得分:1)
我在这里看不到这种行为。你能试试我的样品吗?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using NLog;
using System.Globalization;
using System.Threading;
namespace Mvc4Application.Controllers
{
public class GeoCodingTask
{
public string Photoid{get;set;}
}
public class User
{
public List<GeoCodingTask> PhotoGeocodingTasks {get;set;}
}
public class HomeController : Controller
{
private static Logger _logger = LogManager.GetCurrentClassLogger();
public ActionResult SetupCoordinatesTask()
{
User user = new User{ PhotoGeocodingTasks = new List<GeoCodingTask>()};
user.PhotoGeocodingTasks.Add(new GeoCodingTask{ Photoid= "id1"});
user.PhotoGeocodingTasks.Add(new GeoCodingTask { Photoid = "id2" });
Session["User"] = user ;
return View("GetCoordinatesTask");
}
public ActionResult GetCoordinatesTask()
{
User user = (User)Session["User"];
if (user == null)
{
_logger.Error("No user in session!");
return View();
}
if (user.PhotoGeocodingTasks == null )
_logger.Debug("PhotoGeocodingTasks - null " );
if (user.PhotoGeocodingTasks.Count == 0)
{
_logger.Debug("Pre-processing - PhotoGeocodingTasks.Count" + user.PhotoGeocodingTasks.Count);
return View();
}
lock (user.PhotoGeocodingTasks)
{
_logger.Debug("Pre-processing - PhotoGeocodingTasks.Count" + user.PhotoGeocodingTasks.Count);
var task = user.PhotoGeocodingTasks[0];
if (!user.PhotoGeocodingTasks.Remove(task))
_logger.Error("Could not remove geocoding task after picking it up!");
_logger.Debug("Post processing - SessionID: " + Session.SessionID);
_logger.Debug("Post processing - PhotoGeocodingTasks.Count" + user.PhotoGeocodingTasks.Count);
return View();
}
}
}
}
我先拨打http://localhost:1631/home/SetupCoordinatesTask设置会话,然后再拨2次http://localhost:1631/home/GetCoordinatesTask
结果是
thread:19|2012-01-20 22:12:51.0492|DEBUG|Mvc4Application.Controllers.HomeController|Pre-processing - PhotoGeocodingTasks.Count2
thread:19|2012-01-20 22:12:51.0652|DEBUG|Mvc4Application.Controllers.HomeController|Post processing - SessionID: e4tawytx2mfq2msc3y2ajzl3
thread:19|2012-01-20 22:12:51.0652|DEBUG|Mvc4Application.Controllers.HomeController|Post processing - PhotoGeocodingTasks.Count1
thread:10|2012-01-20 22:13:01.0928|DEBUG|Mvc4Application.Controllers.HomeController|Pre-processing - PhotoGeocodingTasks.Count1
thread:10|2012-01-20 22:13:01.0928|DEBUG|Mvc4Application.Controllers.HomeController|Post processing - SessionID: e4tawytx2mfq2msc3y2ajzl3
thread:10|2012-01-20 22:13:01.0928|DEBUG|Mvc4Application.Controllers.HomeController|Post processing - PhotoGeocodingTasks.Count0
thread:15|2012-01-20 22:13:02.6698|DEBUG|Mvc4Application.Controllers.HomeController|Pre-processing - PhotoGeocodingTasks.Count0
您能简化一下内容代码并发布完整样本吗?
答案 1 :(得分:1)
开发人员错误。令人尴尬,但我有一个错误,我在处理完最后一个任务后继续创建一个新任务。我很想删除这个问题:)
感谢您在Malcom的所有时间。