【问题标题】:C# async await From Controller [duplicate]C#异步等待来自控制器[重复]
【发布时间】:2014-02-14 10:40:57
【问题描述】:

我有一个 ASP.Net MVC 控制器,它调用一个将发布采购订单的方法。但是,我希望在后台进行采购订单过帐,我不希望控制器在返回之前等待采购订单过帐。发布需要很长时间,如果出现错误,网站用户确实无能为力,需要提醒其他人。

这似乎是使用 C# await 和 async 功能的好案例,但我正在努力让它工作。我尝试将发布采购订单的方法设置为异步方法。但是我遇到了以下问题:

  • 具有发布采购订单方法的类实现了一个接口。控制器正在使用接口,您不能将异步放在接口中的方法上。所以我试图通过让该方法返回一个任务来解决这个问题。
  • 过帐采购订单的方法不是异步运行,而是像普通方法一样同步运行。

我做错了什么?代码如下:

public class POReceivingController : Controller
{
    IPOReceivingService poservice;

    public POReceivingController(IPOReceivingService poserviceparm)
    {
        poservice = poserviceparm;
    }

    public ActionResult PostPO(string shipmentid)
    {
        poservice.PostPOAsync(shipmentid);
    }
}

public interface IPOReceivingService
{
    Task PostPOAsync(string shipmentidparm);
}

public class POReceivingService : IPOReceivingService
{
    public async Task PostPOAsync(string shipmentidparm)
    {
        // Code to post PO and alert correct people if there is an error.
    }
}

【问题讨论】:

  • @RobertHarvey 提供的链接解释了为什么你不应该做“一劳永逸”的方法......如果你确实有长时间运行的操作,你应该考虑一些额外的系统来执行操作并让用户分别跟踪进度/完成情况。
  • 像 Windows 服务。
  • 听起来我的处理方式是错误的。我确实需要确保该方法完成并且不会被杀死。我将采取不同的方法。感谢您的帮助。

标签: c# asp.net asp.net-mvc asynchronous


【解决方案1】:

正如我在博客中解释的那样,async doesn't change the HTTP protocol。使控制器动作async 不会导致响应提前发送。

要正确执行此操作,请将请求保存到持久队列(例如,Azure 队列或 MSMQ),并有一个独立的后端(例如,Azure 辅助角色或 Win32 服务)来执行处理和故障通知。

【讨论】:

    【解决方案2】:

    你让这变得比它需要的更复杂。如果您只想启动另一个线程为您做一些工作而不用担心它,您需要做的就是列出以下内容:

    public ActionResult PostPO(string shipmentid)
        {
            Task.Run(() => PostPOAsync(shipmentid));
            Return view();
        }
    

    【讨论】:

      猜你喜欢
      • 2018-06-08
      • 2012-10-14
      • 1970-01-01
      • 2018-03-12
      • 1970-01-01
      • 1970-01-01
      • 2020-02-11
      • 1970-01-01
      • 2021-12-30
      相关资源
      最近更新 更多