在后台使用Perfom CreateAsync和UpdateAsync

时间:2016-05-17 10:01:13

标签: c# asp.net-mvc async-await

我的情况是我在数据库中创建对象以及保存和更新这些对象。我有一个对象插槽计划,默认情况下,它有大约123个插槽对象,我必须将它们写入数据库。

根据具体情况,我必须创建许多插槽计划,因此创建和更新可能会发生数百次或数千次,这非常耗时。 (创建10个插槽计划对我来说持续了大约3分钟)

我知道这真的需要时间,但是如何在后台运行创建和更新并允许用户继续在程序中导航到与插槽和插槽计划无关的部分?

以下是我当前代码的片段:

    [HttpPost]
    public ActionResult BookingRequestDetails(BookingRequestDetails model)
    {
        //Omitted code
        if(shipmentinfo.ShipmentType.Equals("Export"))
            CreateSlotPlan((DateTime)shipmentinfo.PickupDate, (DateTime shipmentinfo.PickupDateLast);

        return RedirectToAction("Home");
    }

public void CreateSlotPlan(DateTime firstdate, DateTime lastdate)
    {
        for (DateTime i = firstdate; i <= lastdate; i = i.AddDays(1))
        {
            SlotPlan slotplan = slotplanmanager.FindByDate(i);
            if (slotplan == null)
            {
                slotplan = new SlotPlan { Date = i };
                slotplanmanager.CreateSlotPlan(slotplan);

                for (int j = 1; j <= 9; j++)
                {
                    Slot slot = new Slot
                    {
                        Location = "A" + j
                    };

                    slotmanager.CreateSlot(slot);
                    slotplan.Slots.Add(slot);
                    slotplanmanager.UpdateSlotPlan(slotplan);
                    slotmanager.UpdateSlot(slot);
                }

                for (int j = 1; j <= 36; j++)
                {
                    Slot slot = new Slot
                    {
                        Location = "B" + j
                    };

                    slotmanager.CreateSlot(slot);
                    slotplan.Slots.Add(slot);
                    slotplanmanager.UpdateSlotPlan(slotplan);
                    slotmanager.UpdateSlot(slot);
                }

                for (int j = 1; j <= 12; j++)
                {
                    Slot slot = new Slot
                    {
                        Location = "C" + j
                    };

                    slotmanager.CreateSlot(slot);
                    slotplan.Slots.Add(slot);
                    slotplanmanager.UpdateSlotPlan(slotplan);
                    slotmanager.UpdateSlot(slot);
                }

                for (int j = 1; j <= 6; j++)
                {
                    Slot slot = new Slot
                    {
                        Location = "D" + j
                    };

                    slotmanager.CreateSlot(slot);
                    slotplan.Slots.Add(slot);
                    slotplanmanager.UpdateSlotPlan(slotplan);
                    slotmanager.UpdateSlot(slot);
                }

                for (int j = 1; j <= 60; j++)
                {
                    Slot slot = new Slot
                    {
                        Location = "E" + j
                    };

                    slotmanager.CreateSlot(slot);
                    slotplan.Slots.Add(slot);
                    slotplanmanager.UpdateSlotPlan(slotplan);
                    slotmanager.UpdateSlot(slot);
                }
            }
        }
    }

代码“return RedirectToAction(”Home“);”除非“CreateSlotPlan(DateTime firstdate,DateTime lastdate)”完成,否则不会执行。我读到使用async-await可以解决我的问题。但我不知道如何在我当前的代码中进行异步编程。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

如果您确实需要立即重定向,然后将此工作排队,则可以使用HostingEnvironment.QueueBackgroundItem来完成此操作。您可以从SO Q & A获得一些见解。你的控制器入口点看起来像这样:

[HttpPost]
public ActionResult BookingRequestDetails(BookingRequestDetails model)
{
    // Omitted code
    if(shipmentinfo.ShipmentType.Equals("Export"))
    {
        // This will return immediately, but the work will be queued up
        HostingEnvironment.QueueBackgroundItem(() =>
            CreateSlotPlan((DateTime)shipmentinfo.PickupDate, 
                           (DateTime)shipmentinfo.PickupDateLast));
    }

    return RedirectToAction("Home");
}
  

计划可以在后台运行的任务,与任何请求无关。