Link to home
Start Free TrialLog in
Avatar of Larry Brister
Larry BristerFlag for United States of America

asked on

C# await task not proceeding?

I am running this in a WinForm... and it stops at the await part
Then
When I stop the degugger
The email sends

How do I change his so either a MessageBox pops up or the form closes?

        public Form1()
        {
            InitializeComponent();
            Execute().Wait();
        }

        static async Task Execute()
        {
            try
            {
                var apiKey = "meApiKey";
                var client = new SendGridClient(apiKey);
                var from = new EmailAddress("noreply@mycompany.com", "Support");
                var subject = "Sending with SendGrid is Fun";
                var to = new EmailAddress("lrbrister@theircompany.com", "LBrister");
                var plainTextContent = "AND... easy to do anywhere, even with C#";
                var htmlContent = "<strong>nd easy to do anywhere, even with C#</strong>";
                var msg = MailHelper.CreateSingleEmail(from, to, subject, plainTextContent, htmlContent);
                var response = await client.SendEmailAsync(msg);
                string s = "Test";
            }
            catch (Exception e)
            {
                Console.WriteLine("{0} Exception caught.", e);
            }
        }

Open in new window

Avatar of gr8gonzo
gr8gonzo
Flag of United States of America image

First, change Execute().Wait();  to just Execute(). Or if you don't want the warning:
_ = Execute();

Open in new window


It's almost always a bad idea to make a constructor wait for something. You want the object (in this case the Form1 instance) to create as fast as possible. The intention of async is to allow Execute() to run the code without holding up the UI thread.

If you want a message box to show up after the email is sent, just add a MessageBox.Show() afterwards, like:
var response = await client.SendEmailAsync(msg);
MessageBox.Show("Response status code: " + response.StatusCode.ToString());

Open in new window


If you're using a debugger to stop on the "await" line, then you're technically pausing the code BEFORE SendEmailAsync runs. A breakpoint anywhere else outside of the Execute() method will probably get hit because the UI thread is continuing on while SendEmailAsync runs.

ASKER CERTIFIED SOLUTION
Avatar of HainKurt
HainKurt
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
You don't want to remove await if you care about the result (e.g. show the message box after the SendEmailAsync completes).

For example, if you take out the await:
var response = client.SendEmailAsync(msg); 
MessageBox.Show("success!");

Open in new window


First, "response" is now a Task object, not a result / response.

Second, a "success!" message box would show up -immediately-, even though the email hadn't been sent just yet. So if there was an exception thrown from inside SendEmailAsync, then  you'd still get a "success" message first and then later on, the exception would arise.

twilio says

User generated imagehttps://github.com/sendgrid/sendgrid-csharp/blob/main/TROUBLESHOOTING.md#error

error codes are here
https://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/errors.html

actually, the result of request is something that should be setup on twilio...
They can call a page/webservice with result for that request, so you can check later...

also, they suggest something like this

If your UI based requests are failing, it may be due to a little known issue where the UI only has a single thread.
var response = await client.SendEmailAsync(msg).ConfigureAwait(false);

Open in new window


All the more reason not to skip the await. You won't be able to tell if it fails if you don't use await.