【问题标题】:Shared session state access between Controllers invoked via AJAX通过 AJAX 调用的控制器之间的共享会话状态访问
【发布时间】:2011-01-31 15:44:30
【问题描述】:

我正在尝试为由 AsyncController 实现的长时间运行的请求提供进度监控机制。网页调用(通过 JQuery $.post)以下控制器上的异步 StartTask 操作...

[NoAsyncTimeout]
public class TaskController: AsyncController
{
   [HttpPost]
   public void StartTaskAsync()
   {
      AsyncManager.OutstandingOperations.Increment();
      Session["progress"] = "in progress";
      Task.Factory.StartNew(DoIt);
   }

   public ActionResult StartTaskCompleted()
   {
      return Json(new {redirectUrl = Url.Action("TaskComplete", "First")});
   }

   private void DoIt()
   {
      try
      {
         // Long-running stuff takes place here, including updating 
         // Session["progress"].
      }
      finally
      {
         AsyncManager.OutstandingOperations.Decrement();
      }
   }
}

同一网页设置了一个 2 秒的计时器(通过 window.setInterval)来调用以下对会话具有只读访问权限的控制器(通过 JQuery $.getJSON)...

[SessionState(SessionStateBehavior.ReadOnly)]
public class ProgressController: Controller
{
    [HttpGet]
    public ActionResult Current()
    {
       var data = Session["progress"];
       return Json(data, JsonRequestBehavior.AllowGet);
    }
}

getJSON 返回后调用的函数会更新一个 DIV 以显示当前进度。最终,进度将在会话中通过“长时间运行的东西发生在这里”代码进行更新,但由于它是对 ProgressController.Current() 的调用,因此在会话中找不到任何数据并始终返回 null。

我曾假设从同一个浏览器发送到同一个 IIS 服务器的 JQuery AJAX 请求会以相同的会话结束,但似乎并非如此。我是否需要在这些 $.post 和 $.getJSON 调用上显式设置 ASP.NET 会话密钥?还是不能以这种方式在控制器之间共享会话状态(即使一个具有 R/O 访问权限)(我可以回退到使用应用程序状态和 GUID 的稍微笨拙的解决方案)。

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3


    【解决方案1】:

    这是正常行为。您的 StartTask 操作会阻塞,直到它完成。在 DoIt 方法完成执行之前,它不会返回任何响应。我想这就是您使用 AJAX $.post 调用它的原因。问题是,当此方法运行并写入会话时,来自同一会话的所有其他请求将由 ASP.NET 引擎排队。您不能同时从会话中写入和读取。您必须为会话以外的进度数据找到另一个线程安全存储。

    【讨论】:

    • StartTask 动作真的会阻塞吗?我认为 StartTaskAsync 方法返回(我认为这是我在调试器中观察到的,将再试一次)并且 ASP.NET 工作线程返回到池中,直到收到 AsyncManager.OutstandingOperations.Decrement() 调用(尽管如何ASP.NET MVC 将调用 Decrement() 的线程与我不确定的相应 XxxCompleted() 操作方法相关联。 StartTaskAsync 不会阻止从同一个浏览器实例对 ProgressController.Current() 的调用,只是 ProgressController.Current() 没有看到同一个会话。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-11
    • 2019-01-27
    • 1970-01-01
    • 1970-01-01
    • 2012-08-30
    • 1970-01-01
    • 2016-06-17
    相关资源
    最近更新 更多