2017-12-09 6 views
0

Ich versuche zu verstehen, async und Task mit await, nicht sicher, ob ich es noch bekomme, da meine Anwendung nicht so reagiert, wie ich dachte, es funktioniert.Verständnis async Aufgabe und erwarten mit SendGrid

Ich habe ein MVC-Projekt und in einem Controller ist eine Methode, die auf Speichern ausgeführt wird. Diese Methode macht ein paar Dinge, aber der Hauptpunkt, auf den ich mich konzentriere, ist das Senden einer Email an 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) 
     //... 
} 

Innen Execute():

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 = "<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(); 

} 

Nun, da ich meinen Code skizziert habe (wahrscheinlich schreckliche Praktiken), ich hatte gehofft, async Aufgabe besser zu verstehen und zu verbessern, was ich zu tun versucht bin.

Wie kann ich auf var iResponse = await client.SendEmailAsync(msg); warten und speichern Sie es in meiner Datenbank richtig. Zulassen, dass die Anwendung fortgesetzt wird (nicht die Benutzererfahrung unterbrechen).

Bitte lassen Sie mich wissen, wenn ich weitere Informationen hinzufügen sollte.

+0

Empfiehlt SendGrid wirklich 'Wait()' zu verwenden? Sie sollten Ihren Controller asynchron machen und den Aufruf "erwarten", nicht mit Warten blockieren. – Crowcoder

+0

Ich überprüfe die andere Frage @ Clint, danke. – Derek

+0

SendGrid hat .Wait() im [Erste Schritte] (https://app.sendgrid.com/guide/integrate/langs/csharp) @Crowcoder. – Derek

Antwort

1

Sie können Ihren Controller async durch Rückkehr Task und dann await der Anruf statt Wait machen.

[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(); 
    ..... 
}