无法取消MVC中的异步操作

时间:2017-09-27 21:17:11

标签: c# asp.net-mvc asynchronous

在我看来,我有两个按钮,一个调用Start()动作,另一个调用Stop()。这是控制器的样子:

public class TestController : AsyncController
{
    public static CancellationTokenSource cts = new CancellationTokenSource();

    public void StartAsync()
    {
        cts = new CancellationTokenSource();
        CancellationToken cancellationToken = cts.Token;
        AsyncManager.OutstandingOperations.Increment();

        AsyncManager.Parameters["task"] = Task.Factory.StartNew(() =>
        {
            try
            {
                while() {
                    if (cancellationToken.IsCancellationRequested)
                        break;

                    // Do stuff
                }
            }
            finally
            {
                AsyncManager.OutstandingOperations.Decrement();
            }
        }, cancellationToken);
    }

    public ActionResult StartCompleted(Task task)
    {
        try
        {
            task.Wait();
            return Json(new { success = true }, JsonRequestBehavior.AllowGet);
        }
        catch (Exception e)
        {
            return Json(new { success = false }, JsonRequestBehavior.AllowGet);
        }
    }

    public void StopAsync()
    {
        cts.Cancel();
    }

    public ActionResult StopCompleted()
    {
        return Json(new { success = true }, JsonRequestBehavior.AllowGet);
    }
}

但是当我单击停止按钮时,只有在Start完成后才会调用Stop动作。我该如何停止行动?

2 个答案:

答案 0 :(得分:2)

引自Pro .NET Performance:

一书
  

取消已经执行的工作需要来自执行该工作的代码的合作。但是,尚未开始执行的任务可以完全取消,不会产生任何恶性后果。

这意味着在Task lambda中你需要检查工作是否已被取消并采取相应的行动。例如:

if (cts.IsCancellationRequested) return;

您是否在检查取消请求?

更新

检查需要在// Do stuff部分的某个地方。因此,例如,如果您将复杂的多部分计算作为一项任务运行,您必须循环数百个项目,进行一些处理并在结束时返回一些结果,您可以在循环的每次迭代开始时检查取消

或者另一个例子,如果您在任务中使用了支持取消的API(例如HttpClient.GetAsync),那么您必须将CancellationToken传递给该API适当的重载。

答案 1 :(得分:0)

我需要使用

[SessionState(SessionStateBehavior.ReadOnly)]

允许我的控制器异步处理请求。由于我使用的是MVC 2并且该属性不可用,因此我必须创建一个自定义路由处理程序。 Serdar对这个问题的回答帮助了我:Disable Session state per-request in ASP.Net MVC