直到async函数的回调完成后,View才会显示出来

本文关键字:View 显示 函数 async 回调 直到 | 更新日期: 2023-09-27 18:11:45

我想做的是:

  1. 我有一个网页,这是一个ASP。. NET MVC页面;
  2. 我想在有人通过我的页面发布信息后发送后台通知电子邮件;
  3. 如果发送失败,则通知邮件不重要;

我使用async调用SendAsync()。我跟踪了代码,控制器返回了,async方法也返回了,但不知何故,直到回调完成后,View才显示在浏览器中。因此,实际上这使得async函数毫无意义。

我不知道为什么,有人知道ASP里面发生了什么吗?。NET MVC框架?下面是我的代码示例:

(Controller.cs)
    [HttpPost]
    public ActionResult Index(MyModel myModel)
    {
        if (ModelState.IsValid)
        {
            if (_myService.ProcessForm(myModel))
            {
                Task t = Task.Factory.StartNew(() => 
                    _notificationService.SendEmail(myModel.Message));
            }
            return RedirectToAction("ThankYou");
        }
        return View(myModel);
    }

(NotificationService.cs)
public class NotificationService : INotificationService
{
    //ingore codes for brief
    public NotificationService()
    {
    }
    private bool SendMessage(string msg)
    {
        try
        {
            // Specify the message content.
            message = new MailMessage(fromAddr, toAddr);
            message.Body = msg;
            message.BodyEncoding = System.Text.Encoding.UTF8;
            message.Subject = "Notification";
            message.SubjectEncoding = System.Text.Encoding.UTF8;
            // Set the method that is called back when the send operation ends.
            client.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
            string userState = message.Body;
            client.SendAsync(message, userState);
        }
        catch (InvalidOperationException ex)
        {
            //Console.Write(ex.Message);
        }
        catch (SmtpFailedRecipientsException ex)
        {
        }
        catch (SmtpException ex)
        {
        }
        catch (Exception ex)
        {
        }
        return true;
    }
    public void SendEmail(string msg)
    {
        Task.Run(() => SendMessage(msg));
    }
    private void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
    {
        // Get the unique identifier for this asynchronous operation.
        String token = (string)e.UserState;
        if (e.Cancelled)
        {
            //Console.WriteLine("[{0}] Send canceled.", token);
        }
        if (e.Error != null)
        {
            //Console.WriteLine("[{0}] {1}", token, e.Error.ToString());
        }
        else
        {
            //Console.WriteLine("Message sent.");
        }
        // Clean up.
        if (message != null)
            message.Dispose();
    }
结果:

代码在SendCompletedCallback()完成之前,我的"Thank you"页面不会显示在浏览器中。

我会在心里弹出一个感谢大家的页面!:)

直到async函数的回调完成后,View才会显示出来

看一个类似的问题和答案。考虑到HTTP是面向连接的,一般来说,将结果返回给客户端并在服务器上继续处理不会返回给客户端的内容(至少不是通过该HTTP会话)是没有意义的。

你想要启动一些无关紧要的过程,比如发送电子邮件,当然是特殊情况。您可以在原始链接中使用解决方案。或者,您可以创建一个AJAX请求来触发这个次要进程。

如jQuery示例

//Do GET request to gather HTML
//Do POST to fire off email
$('#sendEmail').click(function () {
            $.ajax({
                url: "/Api/SendEmail",
                type: "POST",
                data: {
                    //...                 
                }
            }).done(function () {
                console.log('email sent');
            });