Asp.Net mvc,如何制作异步和等待方法

时间:2017-10-01 12:17:37

标签: asp.net-mvc asynchronous async-await

我使用这两个操作在订购时向管理员发送有关库存状态的电子邮件... 但是当我调用SendEmailToAdminUser时...它需要时间并排,我不能与其他功能一起工作......等待litle long .. 我想将这些函数更改为异步并等待任务...但我不知道如何做。我试图从JsonResult改为ActionResult ......

public JsonResult SendEmailToAdminUser()
{
    bool result = false;

    var emails = UserEmails();

    if (emails != null)
    {
        foreach (var email in emails)
        {
            var departmentId = context.Users.Where(e => e.Email == email)
                .Select(s => s.DepartmentId).FirstOrDefault();

            string departmentname = context.Departments.Where(u => u.deptId == departmentId)
                .Select(n => n.DepartmentName).Single();

            int[] ProductId = context.Inventory.Where(s => s.prId == departmentId)
                .Where(s => s.Status == 10).Select(s => s.PrId).ToArray();

            foreach (var product in ProductId)
            {
                string productname = context.Products.Where(n => n.prId == product)
                    .Select(n => n.ProductName).Single();

                result = SendEmail(email, productname, "<p> Hi there, <br />It is time to order " 
                    + productname + " to department: " + departmentname + "</p> <br /> /Regards");
            }
        }
    }

    return Json(result, JsonRequestBehavior.AllowGet)
}

我的SendEmail功能是:

public bool SendEmail(string toEmail, string subject, string emailBody)
{
    try
    {
        string senderEmail = System.Configuration.ConfigurationManager.AppSettings["SenderEmail"].ToString();
        string senderPassword = System.Configuration.ConfigurationManager.AppSettings["SenderPassword"].ToString();

        SmtpClient client = new SmtpClient("smtp.gmail.com", 587);
        client.EnableSsl = true;
        client.Timeout = 100000;
        client.DeliveryMethod = SmtpDeliveryMethod.Network;
        client.UseDefaultCredentials = false;
        client.Credentials = new NetworkCredential(senderEmail, senderPassword);

        MailMessage mailMessage = new MailMessage(senderEmail, toEmail, subject, emailBody);
        mailMessage.IsBodyHtml = true;
        mailMessage.BodyEncoding = UTF8Encoding.UTF8;
        client.Send(mailMessage);

        return true;
    }
    catch(Exception ex)
    {
        return false;
    }
}

1 个答案:

答案 0 :(得分:1)

正如评论者所提到的,你不会从async / await中获得任何好处,因为你只是为其他请求释放底层线程。实际执行时间可能更长比您现有的更长

听起来你真正想要的是并发性,可以使用2017-09-24 轻松实现。但是,在使代码复杂化之前,我建议先进行一些更改。

  • 重复使用Parallel.ForEach的实例。每次调用实例化都会产生开销,因为每次调用都需要连接到后端SMTP服务。
  • Shyju指出,优化你的算法。现在,您正在循环中向相同的电子邮件地址发送多封电子邮件。您可以将这些合并在一起,以最大限度地减少对SmtpClient的调用量。
  • 通过一次调用多个内容,最大限度地减少您正在进行的数据库调用次数。

从上面的代码:

SendMail

这是相当抛在一起,但希望能给你一个开始。从本质上讲,您只需要尽量减少您正在进行的I / O量,您应该看到实质性的改进!