无法在按钮单击c#mvc时立即中断循环

无法在按钮单击c#mvc时立即中断循环,c#,.net,asp.net-mvc,while-loop,C#,.net,Asp.net Mvc,While Loop,我有mvc操作方法,其中while循环正在运行,我想在另一个按钮上停止while循环,这样我就可以维护一个标志,并将其设置为false以中断循环 bool flag = true; public async Demo() { while(flag == true) { do something... } } 现在点击按钮,我调用一个动作方法来停止while循环- public ActionResult StopLoop() { flag = false

我有mvc操作方法,其中while循环正在运行,我想在另一个按钮上停止while循环,这样我就可以维护一个标志,并将其设置为false以中断循环

bool flag = true;

public async Demo()
{
while(flag == true)
{
do something...
}
}
现在点击按钮,我调用一个动作方法来停止while循环-

    public ActionResult StopLoop()  
    {  
        flag = false;
        Return View("Index")
    }  
但在点击按钮后,点击这个
停止循环
几乎需要一分钟的时间

为什么??可能所有人都在同一个UI页面上,共享相同的
homecontroller
我能耍什么花招吗


当循环开始时,我在一个按钮请求上有两个按钮,我想打开 另一个按钮单击请求循环停止


若你们想并行运行两个任务,你们需要为第二个任务使用新线程,同时你们需要有条件地停止第二个线程

CancellationTokenSource TokenSource = new CancellationTokenSource();
CancellationToken Ct = TokenSource.Token;

Task Demo = Task.Run(() =>
{
    do
    {
        Thread.Sleep(1000);
        Trace.Write("loop");
    } while (!Ct.IsCancellationRequested);
}, Ct);

bool Flag = true;

if (Flag)
{
    TokenSource.Cancel();
}
您可以在这里看到有关异步编程的更多信息

大约


更新

若要在web应用程序中执行此操作,必须在一个线程中运行第二个任务,该线程在请求完成后不会终止

public class MvcApplication : System.Web.HttpApplication
{
    static Task Demo = null;
    static CancellationTokenSource TokenSource = null;
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);


        TokenSource = new CancellationTokenSource();
        CancellationToken Ct = TokenSource.Token;

        Demo = Task.Run(() =>
        {
            do
            {
                Thread.Sleep(1000);
                Trace.Write("loop");
            } while (!Ct.IsCancellationRequested);
        }, Ct);
    }

    public static void CancelLoop()
    {
        TokenSource.Cancel();
    }
}

您必须通过请求取消第二个任务(包含while循环)。 例如:

public class HomeController : Controller
        {
            public JsonResult ButtonPressed()
            {
                MvcApplication.CancelLoop();

                return Json("canceled", JsonRequestBehavior.AllowGet);
            }
        }

如果您说一个请求启动while循环,而您希望另一个请求停止它,那么ASP.NET MVC是不可能的,因为它是无状态的。返回视图后,while循环将不再运行。在您的例子中,
StopLoop
方法看起来只需要一分钟就可以命中。真正可能发生的情况是,while循环可能正在无休止地运行,IIS会杀死它,然后处理停止循环请求。

两个技巧:1)
StopLoop
在另一个线程中执行:尝试使
标志
字段
不稳定。2) 您的“做某事”需要很长时间,而且您很少轮询标志。您的mvc应用程序是无状态的,因此当您设置
flag=false
时,它与发送第一个响应时的
flag
实例不同。请尝试将标志值传递给UI作为回报,然后返回并在控制器中读取它。可能是
TempData
在任何web应用程序(任何语言、任何堆栈)中都很有用,不同的请求具有不同的状态/上下文。也许真正的问题是如何在ASP.NET MVC中运行一个长期运行的作业?@Neo check。这不仅是因为你的代码不能被另一个操作取消,它甚至可能不会运行足够长的时间。即使是在桌面应用程序中,尝试访问这样的全局字段也肯定会因竞争条件而失败web应用程序的最佳方法是什么?您应该在application_start(global.asax)中调用while任务,该任务只适用于小型应用程序。那么在多个服务器场节点上运行的应用程序呢?我没有关于服务器场的信息,但在iis上有一个web应用程序和应用程序池之前,它将一直工作,而不考虑服务器的数量。有一条基本规则迫使我们使用startup.cs,在web应用程序中,请求完成后,所有内容都应该从服务器上清除,而不是从引用启动的对象中清除。cs,如果您在请求中创建任务,则在请求完成后,任务将被取消,因为父任务goneright正在以较小的数量执行它,这就是为什么它需要几分钟的原因,我担心规模太大会没完没了:(还有其他停止循环的方法吗?循环开始时,我在一个按钮请求上有两个按钮,我想在另一个按钮上单击请求循环停止。在MVC中,你不能单击一个按钮来启动一个进程,然后单击另一个按钮来停止它。如果你使用的是桌面应用程序,你完全可以做你所描述的事情,因为你有c完全控制所有线程。在MVC中,一旦您从控制器返回,您就失去了对所有线程的控制,无法再与它们交互。返回视图后,您的请求不会在服务器上持久存在。我建议您阅读Scott Hanselman的文章。在这篇文章中,他谈到了处理运行的作业的几个不同选项独立于您的站点(Azure Webjobs等),这可能会为您指明作为应用程序一部分运行后台进程的正确方向。但他正在使用nuget
WebBackgrounder
为什么要使用它:(它是旧的,没有其他类似的方法来实现吗?提前感谢