Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 会话变量导致控制器操作一次触发一个_C#_Ajax_Asp.net Mvc - Fatal编程技术网

C# 会话变量导致控制器操作一次触发一个

C# 会话变量导致控制器操作一次触发一个,c#,ajax,asp.net-mvc,C#,Ajax,Asp.net Mvc,我有一个控制器,它一次执行一个操作,就像它将我的请求放入队列,然后依次响应每个请求一样。因此,例如,如果我单击设置为发布到我的控制器的2个或3个按钮,控制器最终将触发所有操作,但在我单击该按钮时不会正确 在拆开我的项目后,我意识到这种奇怪的行为不知何故是由在默认控制器操作中设置会话变量引起的 控制器: [HttpGet] public ActionResult Index() //Start Page { System.Web.HttpContext.Current.Session["S

我有一个控制器,它一次执行一个操作,就像它将我的请求放入队列,然后依次响应每个请求一样。因此,例如,如果我单击设置为发布到我的控制器的2个或3个按钮,控制器最终将触发所有操作,但在我单击该按钮时不会正确

在拆开我的项目后,我意识到这种奇怪的行为不知何故是由在默认控制器操作中设置会话变量引起的

控制器:

[HttpGet]
public ActionResult Index() //Start Page
{
    System.Web.HttpContext.Current.Session["SomeString"] = "SomeValue";
    return View();
}

[HttpPost]
public void Run(string json)
{
    for (int i = 0; i < 1000000; i++)
    {
        for (int j = 0; j < 1000000; j++)
        {

        }
    }
}
当我删除设置会话变量的代码行时,我可以单击run按钮(启动长时间运行的循环),单击我的“OtherPage”按钮,并立即导航到“OtherPage”视图。如果我设置了会话变量,运行循环,然后单击“OtherPage”按钮,我的应用程序将挂起,直到循环完成,然后导航到“OtherPage”视图


有人知道为什么会发生这种情况吗?

你的问题的简短答案是:

HostingEnvironment.QueueBackgroundWorkItem(()=>{//your code})
长而不那么危险的答案是:使用一些队列系统,比如RabbitMQ或AWS SQS或MSMQ或其他什么。网络应用程序上的后台任务不是你一生中能做的最好的事情,即使响应(成功或失败)对你来说并不重要

编辑

如果您使用的是会话状态,您可能需要在需要一些并行性的控制器中禁用会话状态,或者将其设置为只读。在所需的控制器上添加以下属性:

[SessionState(SessionStateBehavior.Disabled)]
public class FooController...
本页解释了为什么在某些情况下需要这样做:


但是,同样,这是一种非常糟糕的做法。您必须处理
ThreadAbortException
s,并且会遇到许多其他问题。

对于web服务器来说,先发后忘是一种糟糕的设计。任何时候都要尽量避免possible@Steve你介意解释一下原因吗?我不必保证任务成功完成。我希望它偶尔会失败,并为这些场景构建日志记录和错误处理。我只是想知道为什么我在使用“异步”技术的时候只专注于一个线程?这并不是因为您在等待调用而触发并忘记<代码>任务。运行(()=>yourMethodCall)将被触发并忽略。您如何确定所有其他操作在开始之前都要等待上一个操作完成?如果是这样的话,我会非常惊讶默认的线程池大小是100。这意味着它可以处理100个并发请求,而不会相互阻塞。除非你有一些锁在你的基本控制器或某种类型的不应该发生。考虑这一点,在使用AppDebug关闭之前只能延迟90秒(实际上是HTTPRunTimeStuts.SutnStudio超时和PurrimeStudioTimeLimIT的最小值)。如果排队的项目太多,无法在90秒内完成,ASP.NET运行时将在不等待工作项完成的情况下卸载AppDomain。我刚刚对这个问题进行了重要的编辑,因为我已经确定了并发请求不可用的原因working@BrandonChurch您必须在要触发并忘记的控制器中设置SessionStateAttribute。我用这些信息编辑了答案。但是,请记住,您不应该在生产代码上使用这种解决方案。@adilsondalmeidajr非常感谢!这背后的原因是为了防止会话数据的脏读吗?这对我来说只是一种快速区分用户的方法,但我认为我应该使用OwinContext。我认为更多的是关于SessionState的工作方式,我查看了提供者的代码。顺便说一句,如今,无状态应用程序将是一个更好的选择。
HostingEnvironment.QueueBackgroundWorkItem(()=>{//your code})
[SessionState(SessionStateBehavior.Disabled)]
public class FooController...