Async和Await - 将立即从MVC操作方法控制返回吗?

时间:2021-01-26 21:07:31

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.

此代码将存在于我正在创建的MVC应用程序中。用户将在浏览器中启动一些操作,并且将调用控制器操作方法,并且最终将在操作方法中调用此电子邮件方法。

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.

我的理解是,一旦执行了最后一行(带有等待的行),控制立即返回给调用者,而DeliverAsync方法完成其任务。假设这是正确的,我们还假设电子邮件需要很长时间才能发送,可能需要30秒。即使DeliverAsync方法仍在尝试执行发送,控制器操作方法是否会将控制权返回给浏览器?理想情况下,这就是我想要发生的事情。

2 个解决方案

#1


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.

你的理解是正确的。不要使用async void,不需要。使用异步任务并确保处理错误。现在你永远不会发现导致崩溃的错误。

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

即使DeliverAsync方法仍在尝试执行发送,控制器操作方法是否会将控制权返回给浏览器?

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, ...).

同样重要的是要注意,ASP.NET中的后台工作可能会在工作进程退出(部署,重新启动,崩溃......)时随时死亡。

#2


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

即使DeliverAsync方法仍在尝试执行发送,控制器操作方法是否会将控制权返回给浏览器?

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.

相反,我建议创建一个在调用控制器时提供请求的队列,以及使队列出列的另一个线程,在异步等待其完成时正确发送消息,并记录可能发生的任何错误。以生产者 - 消费者的执行方式。

#1


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.

你的理解是正确的。不要使用async void,不需要。使用异步任务并确保处理错误。现在你永远不会发现导致崩溃的错误。

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

即使DeliverAsync方法仍在尝试执行发送,控制器操作方法是否会将控制权返回给浏览器?

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, ...).

同样重要的是要注意,ASP.NET中的后台工作可能会在工作进程退出(部署,重新启动,崩溃......)时随时死亡。

#2


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

即使DeliverAsync方法仍在尝试执行发送,控制器操作方法是否会将控制权返回给浏览器?

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.

相反,我建议创建一个在调用控制器时提供请求的队列,以及使队列出列的另一个线程,在异步等待其完成时正确发送消息,并记录可能发生的任何错误。以生产者 - 消费者的执行方式。