简体   繁体   中英

Async and Await - Will control return immediately from an MVC action method?

I'm just learning how to use async and await. Say I have the following method that sends an email:

public async void Send()
{
    // Create a network credentials object
    var credentials = new NetworkCredential(azureUserName, azurePassword);

    // Create an Web transport for sending the email
    var transportWeb = new Web(credentials);

    // Send the email
    await transportWeb.DeliverAsync(this._email);
}

This code will exist in an MVC app I'm creating. The user will initiate some action in the browser and a call will get made to a controller action method and this email method will eventually get called within the action method.

My understanding is that as soon as the last line is executed (the line with the await), control immediately returns to the caller, while the DeliverAsync method completes its task. Assuming that is correct, let's also assume the email is taking a long time to send, maybe 30 seconds. Will the controller action method return control back to the browser even though the DeliverAsync method is still attempting to execute the send? Ideally this is what I would to have happen.

Your understanding is correct. Don't use async void though, there is no need. Use async Task and be sure to process errors. Right now you will never find out about bugs causing crashes.

Will the controller action method return control back to the browser even though the DeliverAsync method is still attempting to execute the send?

That depends on what that method does. It's code is not here. Right now it has no way of awaiting Send so probably yes.

It is also important to note that background work in ASP.NET can die at any time when the worker process exits (deployment, reboot, crash, ...).

Will the controller action method return control back to the browser even though the DeliverAsync method is still attempting to execute the send?

From the fact your method is async void , I'm assuming the controller is simply invoking the method call and returning, so yes, it will end up returning even though the message wasn't actually sent yet.

I would not recommend you use such an approach as for the fact that any exception would be rethrown on an arbitrary threadpool thread and makes no guarantee of actually completing properly. I'm assuming delivery of the message is important to you.

Instead, I'd recommend creating a queue which is fed the request when your controller is invoked, and a different thread that dequeues the queue, properly sends the message while asynchronously waiting for its completion, and perhaps logging any error which have occured. In the fashion of a producer-consumer style of execution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM