关于c#:了解异步任务并等待SendGrid

Understanding async Task and await with SendGrid

本问题已经有最佳答案,请猛点这里访问。

我试图用await来理解asyncTask,不确定我是否能理解,因为我的应用程序没有像我认为的那样响应。

我有一个MVC项目,在控制器内部是一个在保存时运行的方法。这个方法做了一些事情,但我关注的主要项目是向sendgrid发送电子邮件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[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()内:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
static async Task Execute()
{
    var apiKey ="REMOVED";
    var client = new SendGridClient(apiKey);
    var from = new SendGrid.Helpers.Mail.EmailAddress("[email protected]","Example User");
    var subject ="Sending with SendGrid is Fun";
    var to = new SendGrid.Helpers.Mail.EmailAddress("[email protected]","Example User");
    var plainTextContent ="and easy to do anywhere, even with C#";
    var htmlContent ="and easy to do anywhere, even with C#";
    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);并将其保存到我的数据库中?允许应用程序继续(而不是中断用户体验)。

如果我需要更多的信息,请告诉我。


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

1
2
3
4
5
6
7
8
9
10
11
 [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();

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