SmtpClient.SendAsync挡住了我的ASP.NET MVC请求 [英] SmtpClient.SendAsync blocking my ASP.NET MVC Request

查看:241
本文介绍了SmtpClient.SendAsync挡住了我的ASP.NET MVC请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发送一个简单的电子邮件一个动作:

I have a Action that sends a simple email:

    [HttpPost, ActionName("Index")]
    public ActionResult IndexPost(ContactForm contactForm)
    {
        if (ModelState.IsValid)
        {
            new EmailService().SendAsync(contactForm.Email, contactForm.Name, contactForm.Subject, contactForm.Body, true);

            return RedirectToAction(MVC.Contact.Success());
        }
        return View(contactForm);
    }

和电子邮件服务:

    public void SendAsync(string fromEmail, string fromName, string subject, string body, bool isBodyHtml)
    {
        MailMessage mailMessage....
        ....
        SmtpClient client = new SmtpClient(settingRepository.SmtpAddress, settingRepository.SmtpPort);

        client.EnableSsl = settingRepository.SmtpSsl;
        client.Credentials = new NetworkCredential(settingRepository.SmtpUserName, settingRepository.SmtpPassword);
        client.SendCompleted += client_SendCompleted;
        client.SendAsync(mailMessage, Tuple.Create(client, mailMessage));
    }

    private void client_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
    {
        Tuple<SmtpClient, MailMessage> data = (Tuple<SmtpClient, MailMessage>)e.UserState;
        data.Item1.Dispose();
        data.Item2.Dispose();

        if (e.Error != null)
        {

        }
    }

当我发电子邮件,我使用的异步方法,那么我的方法SendAsync立即返回,然后RedirectToAction被调用。但响应(在这种情况下,重定向)由ASP.NET isn't发送,直到client_SendCompleted完成

When I send a email, I am using Async method, then my method SendAsync return immediately, then RedirectToAction is called. But the response(in this case a redirect) isn´t sent by ASP.NET until client_SendCompleted is completed.

下面就是我想明白了:

当看着Visual Studio调试器执行,在SendAsync立即返回(和RedirectToAction的叫法),但直到发送电子邮件什么也没有发生在浏览器中?

When watching the execution in Visual Studio debugger, the SendAsync returns immediately (and RedirectToAction is called), but nothing happens in the browser until email is sent?

如果我把里面的client_SendCompleted,客户留在装货断点....直到我按F5在调试器。

If i put a breakpoint inside client_SendCompleted, the client stay at loading.... until I hit F5 at debugger.

推荐答案

这是由设计。 ASP.NET 会自动等待任何未完成的异步工作完成的要求,如果异步工作是在调​​用底层的的SynchronizationContext 的方式拉开序幕之前完成。这是为了确保,如果你的异步操作尝试与在的HttpContext 的Htt presponse 等互动仍然会留下来。

This is by design. ASP.NET will automatically wait for any outstanding async work to finish before finishing the request if the async work was kicked off in a way that calls into the underlying SynchronizationContext. This is to ensure that if your async operation tries to interact with the HttpContext, HttpResponse, etc. it will still be around.

如果你想要做的真火和放大器;算了,你需要用你的 ThreadPool.QueueUserWorkItem 电话。这将迫使它在一个新的线程池线程上运行,而无需通过去在的SynchronizationContext ,因此请求将便愉快地返回。

If you want to do true fire & forget, you need to wrap your call in ThreadPool.QueueUserWorkItem. This will force it to run on a new thread pool thread without going through the SynchronizationContext, so the request will then happily return.

请注意但是,如果因任何原因的应用程序域是往下走,而你发送仍在进行中(例如,如果你改变了web.config文件,扔下一个新的文件到垃圾桶,应用程序池回收等。 )的异步发送会突然中断。如果你关心的是,看看菲尔Haacks <一个href=\"http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx\">WebBackgrounder对于 ASP.NET ,它让你排队的运行和后台工作(如发送电子邮件)以这样一种方式,这将确保在应用程序域关闭的情况下正常完成。

Note however, that if for any reason the app domain were to go down while your send was still in progress (e.g. if you changed the web.config file, dropped a new file into bin, the app pool recycled, etc.) your async send would be abruptly interrupted. If you care about that, take a look at Phil Haacks WebBackgrounder for ASP.NET, which let's you queue and run background work (like sending an email) in such a way that will ensure it gracefully finishes in the case the app domain shuts down.

这篇关于SmtpClient.SendAsync挡住了我的ASP.NET MVC请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆