Can I call awaitable async method from normal synchronous method?

I have code in ASP.net that sends an email. My application is older using ASP.net Webforms and is not converted over to async methods.

However the method for sending email via SendGrid is async awaitable.

Visual Studio doesn’t complain if I use a discard:

_  = SendASendGridMessage()

Would this cause any crash or deadlock if I do this?

Here is the sample code:

public static void SendNew(string toEmail, string subject, string htmlContent, int domainId, int partyId, string category, int itemId)
{           
    EmailAddress from = new EmailAddress("<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c5a0bda4a8b5a9a085a0bda4a8b5a9a0eba6aaa8">[email protected]</a>");
    EmailAddress to = new EmailAddress(toEmail);
    EmailAddress replyTo = new EmailAddress("<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="90f5e8f1fde0fcf5d0f5e8f1fde0fcf5bef3fffd">[email protected]</a>");
            
    htmlContent = $"<html><body>{htmlContent}</body></html>";           

    var msg = MailHelper.CreateSingleEmail(from, to, subject, null, htmlContent);

    _ = SendASendGridMessage(msg, domainId);
}

// Which will then connect with this method later:

// Summary:
// Make a request to send an email through Twilio SendGrid asynchronously.
//
// Parameters:
//   msg:
//     A SendGridMessage object with the details for the request.
//
//   cancellationToken:
//     Cancel the asynchronous call.
//
// Returns:
//     A Response object.
[AsyncStateMachine(typeof(<SendEmailAsync>d__23))]
public Task<Response> SendEmailAsync(SendGridMessage msg, CancellationToken cancellationToken = default);

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

You can use “Fire and Forget” approach and just call an async method without await just like you did. In fact, it is a good practice to detach time-consuming operations, such as sending emails from the code handling http requests. One thing you need to keep in mind, is that an ASP.NET web application is treated as stateless and the host can decide to off-load your app at any moment, even before your async method completes.

There is a mechanism in ASP.NET Framework to schedule long lasting activities so that the Host will be able to gracefully terminate your application waiting for the scheduled activities

HostingEnvironment.QueueBackgroundWorkItem

using System.Web.Hosting;

...

// Schedule task in a background tread 
Func<CancellationToken, Task> workItem = ct => SendASendGridMessage(...);
HostingEnvironment.QueueBackgroundWorkItem(workItem);

Method 2

You could use something like this:

Task t = new Task(() =>
  {
    if (something == true) 
    {
        DoSomething(e);  
    }
  });
  t.RunSynchronously();

For more details, on this topic you can look at the following:

Synchronously waiting for an async operation, and why does Wait() freeze the program here


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x