【问题标题】:Async action in MVC does not workMVC 中的异步操作不起作用
【发布时间】:2013-07-28 03:49:56
【问题描述】:

我正在尝试在我的异步控制器中执行异步操作。我需要做的就是当我按下视图中的按钮时,它会给我一个警报,指示工作已发送完成。当工作完成后,我可以做一些事情(例如返回一个 json 或重定向到另一个视图)。这是我的代码:

服务器端:

    public void DoWork()
    {
       var a = MakeADelay();
    }

    public async Task<ActionResult> MakeADelay()
    {
       await Task.Delay(5000);
       return  RedirectToAction("UploadComplete");
    }

    public ActionResult UploadComplete()
    {
       return View();
    }

这是我的客户端代码:

        $("#btnAsync").click(function () {
        $.ajax({
            url: '/Upload/DoWork',
            type: "post",
            success: function () {
                alert("Work in Progress!!");
            }
        });
    });

当此代码运行时,一切似乎都按预期执行,但是当服务器端代码到达语句 return RedirectToAction("UploadComplete"); 时,它什么也不做!我认为它在另一个线程中运行。

有什么问题?

第二个问题是 aync 动作实际上是什么意思?我从不希望我的行动等待陈述完成。我总是希望我的操作将作业发送到执行队列并返回给客户端,当作业完成时,我可以以某种方式通知客户端。我怎么能通知客户呢?用 SignalR 什么的?

【问题讨论】:

  • 您是否对 UploadComplete() 操作有看法。你怎么说redirecttoactino什么都不做?
  • 当然我有一个视图对应我的重定向语句。但是当它运行时不会发生重定向!你可以试试这个,让我知道它是否适合你。事实上,我的 UploadComplete() 方法永远不会被执行。断点永远不会命中。
  • 对不起,我不熟悉 asyc 等待部分。所以我可能对你没有帮助。

标签: asp.net-mvc-4 async-await asynccontroller


【解决方案1】:

有什么问题?

在这里:

public void DoWork()
{
   var a = MakeADelay();
}

它的作用是启动MakeADelay,然后立即返回给它的调用者,它大概完成创建响应并发送它。

延迟完成后,您的MakeADelay 将尝试通过调用RedirectToAction 继续执行。但是,该请求的响应已经发送,因此这很可能会导致异常(将被忽略,因为您从未await 任务a)。或者它可能什么都不做,但它肯定不会做的是及时返回并重写已经发送的响应。

第二个问题是 aync 操作的真正含义是什么?

我有一个introduction on the subject,您可能会觉得它有用。我还在我的博客上描述了async does not change the HTTP protocol - 对于每个请求,您仍然只会得到一个响应。您尝试做的是为一个请求发送两个响应,但这是行不通的。

我总是希望我的操作将作业发送到执行队列并返回给客户端,当作业完成时,我可以通过某种方式通知客户端。我怎么能通知客户呢?用 SignalR 什么的?

那么你需要一个队列。我推荐一些具有持久性保证的进程外的东西。例如,Azure 队列、MSMQ、WebSphere MQ 等。

而且,是的,您可以使用 SignalR 进行通知。我建议这样做。

【讨论】:

  • 感谢 Stephen,你是异步领域的佼佼者。这正是我一直在等待的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 2019-09-24
  • 1970-01-01
  • 2022-01-05
  • 1970-01-01
  • 2022-01-16
相关资源
最近更新 更多