簡體   English   中英

這是改變我的asp.net mvc控制器以使用異步調用不同方法的方法嗎?

[英]Is this the way to change my asp.net mvc controller to call different methods using async?

我嘗試更改現有的asp.net mvc控制器代碼,以便用戶不必等待該代碼執行其他任務(例如db.update行),調用外部API並發送電子郵件確認。 我不確定這個新的異步代碼是否會以不希望的方式阻塞我的線程。

這是我過去的“同步” asp.net控制器方法:

[HttpPost]
public ActionResult CompletePackingItem(int packingId, int orderId, int nextOrderId)
{
    List<OrderItem> orders = new List<OrderItem>();
    OrderItem order = new BLOrder().GetOrder(orderId);

    if (order.HasBeenPaid && order.IsLabelPrinted && (order.Status == (int)BLOrder.OrderStatus.WaitingFor || order.Status == (int)BLOrder.OrderStatus.WorkingOn))
    {
        new Shoply.Data.Shared.DLWarehousePackingOperation().UpdateIsCompleted(order.OrderId);
        string htmledInvoice = new Shoply.Business.Invoice.BLInvoice().GetInvoiceHtmlFormatted(order.OrderId, false);
        byte[] pdfByted = BLOrdersPdfExport.SaveOrderAsPdf(htmledInvoice, false);

        new UserMailer().SendOrderShippedEmail(order.OrderId, pdfByted);
        new Shoply.Data.DLOrders().UpdateOrderToHasBeenSent(order.OrderId);

        decimal orderTotalInclDeliveryPrice = order.Total + order.DeliveryPrice;
        bool isSuccess = new QuickpayApiService().CapturePayment(order.TransactionId, orderTotalInclDeliveryPrice);
    }
    return RedirectToAction("index", new { packingId = packingId, orderId = nextOrderId });
}

這是我的新版本:

[HttpPost]
public ActionResult CompletePackingItem(int packingId, int orderId, int nextOrderId)
{
    List<OrderItem> orders = new List<OrderItem>();
    OrderItem order = new BLOrder().GetOrder(orderId);

    if (order.HasBeenPaid && order.IsLabelPrinted && (order.Status == (int)BLOrder.OrderStatus.WaitingFor || order.Status == (int)BLOrder.OrderStatus.WorkingOn))
    {
        new Shoply.Data.Shared.DLWarehousePackingOperation().UpdateIsCompleted(order.OrderId);

        Task.Run(() => AsyncCalling(order));
    }

    return RedirectToAction("index", new { packingId = packingId, orderId = nextOrderId });
}

private void AsyncCalling(OrderItem order)
{
    string htmledInvoice = new Shoply.Business.Invoice.BLInvoice().GetInvoiceHtmlFormatted(order.OrderId, false);
    byte[] pdfByted = BLOrdersPdfExport.SaveOrderAsPdf(htmledInvoice, false);

    new UserMailer().SendOrderShippedEmail(order.OrderId, pdfByted);
    new Shoply.Data.DLOrders().UpdateOrderToHasBeenSent(order.OrderId);

    decimal orderTotalInclDeliveryPrice = order.Total + order.DeliveryPrice;
    bool isSuccess = new QuickpayApiService().CapturePayment(order.TransactionId, orderTotalInclDeliveryPrice);
}

在新版本中,我正在使用“異步”功能,希望它可以直接跳回到用戶並異步處理任務,並希望不會不必要地阻塞線程。 這是以異步方式調用任務的正確方法,還是當我想要使用fireandforget方式處理任務以使控制器立即返回給用戶時,這是正確的方法嗎?

您需要更改您的方法簽名

private void AsyncCalling(OrderItem order)

private Task AsyncCalling(OrderItem order)  

您正在告訴編譯器“我正在執行此任務並將控制權交還給您”。 其余代碼對我來說看起來不錯。

是的,如果您以描述的方式使用Task.Run而不在主asp.net線程(即Task.Wait() )上等待它,則ASP.Net引擎將完成執行主線程而不會被Task.Run和快速返回瀏覽器。 同樣,您將無法讓用戶知道由於Task.Run方法中運行的代碼而導致的結果(它可能引發了異常或成功執行了,用戶將永遠不知道那部分代碼發生了什么)。

但是,當控制權返回給瀏覽器時,asp.net線程池線程仍將被使用,因為Task.Run可能會繼續運行,即使將響應發送回瀏覽器也是如此。 因此,您將快速返回瀏覽器,但是asp.net應用程序無法通過這種方法獲得任何收益。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM