ASP.NET会话在更新时线程之间不同步?

ASP.NET会话在更新时线程之间不同步?,asp.net,session,thread-safety,asp.net-mvc-4,Asp.net,Session,Thread Safety,Asp.net Mvc 4,我有一个返回一些JSON的控制器方法。它将集合从会话中拉出,从集合中取出第一个项目,然后将其从集合中移除。如果方法开始时的计数为1,则现在为0 如果我再次使用相同的方法从会话中检索集合,以检查集合计数是否小于1,则为 到目前为止都很简单 在后续请求中,将再次从会话中提取集合,但集合的计数不是预期的0,而是1。以前删除的项目尚未删除!为什么会这样 尽管如果提出了足够的请求,计数最终确实为零。就好像会话对象在所有线程之间同步大约需要30秒 真的会这样吗?MVC4(也可能是以前的版本?)是否存在一些奇

我有一个返回一些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);
        }
    }
public ActionResult getCoordinateTask()
{
var user=会话[“用户”]作为IUser;
if(user==null)
{
Logger.LogError(这是“会话中没有用户!”);
返回Json(null,JsonRequestBehavior.AllowGet);
}
if(user.PhotoGeocodingTasks==null | | user.PhotoGeocodingTasks.Count==0)
返回Json(null,JsonRequestBehavior.AllowGet);
锁定(用户.PhotoGeocodingTasks)
{
Logger.LogDebug(这是“预处理-PhotoGeocodingTasks.Count”+user.PhotoGeocodingTasks.Count);
var task=user.photogeocodingtask[0];
如果(!user.PhotoGeocodingTasks.Remove(任务))
Logger.LogError(这是“拾取后无法删除地理编码任务!”);
var encodedTask=新字典
{
{“photoid”,task.photoid.ToString(CultureInfo.InvariantCulture)},
{“latlong”,task.Latitude+,“+task.Longitide}
};
LogDebug(这是“后处理-SessionID:+Session.SessionID”);
LogDebug(这是“后处理-PhotoGeocodingTasks.Count”+user.PhotoGeocodingTasks.Count);
返回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键入),并得到了相同的结果。没有其他请求的更新值。这就像我的配置中禁用了同步一样


我也在两台计算机上尝试过这个代码,结果相同。

我在这里看不到这种行为。你能试试我的样品吗

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();
            }
        }

    }
}

您能简化代码并发布完整的示例吗?

开发人员错误。令人尴尬,但我有一个bug,在处理完最后一个任务后,我一直在创建一个新任务。我很想删除这个问题:)


感谢您抽出时间访问所有相同的Malcom。

会话与MVC无关。事实上,我不知道线程是否会同步,因为我的代码在一段时间后停止调用此方法:(我投票将此问题删除为“非建设性”。)因为你发现这实际上是开发人员的错误。哇,感谢你花时间在Malcom上。我复制了你的示例,它按预期工作,添加了一个任务,然后检索它并将其从会话中删除。在你回复之前,我还编写了一些新代码,将任务粘贴到HttpRuntime缓存中,并得到了与没有跨线程相同的坏效果/请求更新(在阅读了说明会话无论如何都存储在缓存下的文档后才有意义)。感觉像是配置问题。我比较了两个应用程序之间的web.configs,并尝试了一些差异,但结果相同。Jay-开发者错误-显然不是:)我知道,令人震惊的行为。
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