使用 SendGrid 了解异步任务和等待 [重复]

Posted

技术标签:

【中文标题】使用 SendGrid 了解异步任务和等待 [重复]【英文标题】:Understanding async Task and await with SendGrid [duplicate] 【发布时间】:2018-05-23 18:04:34 【问题描述】:

我正在尝试用await 理解asyncTask,但我不确定我是否完全明白,因为我的应用程序没有按照我想象的方式响应。

我有一个 MVC 项目,并且在 Controller 中是一个在 Save 上运行的方法。这个方法做了一些事情,但我关注的主要项目是向 SendGrid 发送电子邮件。

[HttpPost]
[ValidateAntiForgeryToken]
private void SaveAndSend(ModelView model)

    //This is never used, but is needed in "static async Task Execute()"
    ApplicationDBContext db = new ApplicationDBContext();

    //First try (like the SendGrid example)
        Execute().Wait();
        //More code, but wasn't being executed (even with a breakpoint)
        //...


    //Second try, removed the .Wait()
        Execute();
        //More code and is being executed (good)
        //...

在 Execute() 内部:

static async Task Execute()

    var apiKey = "REMOVED";
    var client = new SendGridClient(apiKey);
    var from = new SendGrid.Helpers.Mail.EmailAddress("example@example.com", "Example User");
    var subject = "Sending with SendGrid is Fun";
    var to = new SendGrid.Helpers.Mail.EmailAddress("example@example.com", "Example User");
    var plainTextContent = "and easy to do anywhere, even with C#";
    var htmlContent = "<strong>and easy to do anywhere, even with C#</strong>";
    var msg = MailHelper.CreateSingleEmail(from, to, subject, plainTextContent, htmlContent);
    var iResponse = await client.SendEmailAsync(msg);

    //The above ^ is executed (sent to SendGrid successfuly)

    //The below is not being executed if I run the code with no breakpoints
    //If I set a breakpoint above, I can wait a few seconds, then continue and have the code below executed

    //This is an Object I have to save the Response from SendGrid for testing purposes
    SendGridResponse sendGridResponse = new SendGridResponse
    
        Date = DateTime.Now,
        Response = JsonConvert.SerializeObject(iResponse, Formatting.None, new JsonSerializerSettings()  ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore )
    ;

    //This is needed to save to the database, was hoping to avoid creating another Context
    ApplicationDBContext db = new ApplicationDBContext();

    db.SendGridResponses.Add(sendGridResponse);
    db.SaveChanges();


现在我已经概述了我的代码(很可能是可怕的做法),我希望能够更好地理解异步任务并改进我试图完成的任务。

如何等待var iResponse = await client.SendEmailAsync(msg); 并将其正确保存到我的数据库中。允许应用程序继续运行(不中断用户体验)。

如果我应该提供更多信息,请告诉我。

【问题讨论】:

SendGrid 真的推荐使用Wait() 吗?你应该让你的控制器异步并await调用,不要用等待阻塞。 我会检查另一个问题@Clint,谢谢。 SendGrid 在Getting Started@Crowcoder 中有.Wait()。 【参考方案1】:

您可以通过返回Task 然后await 调用而不是Wait 来使您的控制器async

 [HttpPost]
 [ValidateAntiForgeryToken]
 public async Task<IActionResult> SaveAndSend(ModelView model)
 
      //This is never used, but is needed in "static async Task Execute()"
      ApplicationDBContext db = new ApplicationDBContext();

      // Await the Execute method call, instead of Wait()
      await Execute();
    .....

【讨论】:

以上是关于使用 SendGrid 了解异步任务和等待 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

在异步方法中省略异步和等待[重复]

无法理解异步和等待的需求[重复]

在 Parallel.foreach 中等待 [重复]

线程池了解一下

异步/等待和任务

异步/等待上传任务