0

我想做的是:

  1. 我有一个 ASP.NET MVC 页面的网页;
  2. 我想在有人通过我的页面发布信息后,发送通知邮件背景;
  3. 发送失败的通知邮件无关紧要;

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

我不知道为什么,有人知道 ASP.NET MVC 框架内部发生了什么吗?

这是我的代码示例:

(控制器.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);
    }

(通知服务.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() 完成之前,我的“谢谢”页面不会显示在浏览器中。

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

4

1 回答 1

2

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

您想要启动一些切向过程(例如发送电子邮件)的情况当然是例外情况。您可以使用原始链接中的解决方案。或者,您可以创建一个触发此辅助进程的 AJAX 请求。

EG 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');
            });
于 2013-04-30T16:47:02.637 回答