c# – 使用Asp.Net发送SendAsync电子邮件,但Page仍在等待?

我不希望用户等待页面完成发送过程,所以我想在ASP.NET 3.5中使用SendAsync.但是在调试之后,我发现主线程还在等待.

Main: Call send email function...
mailSend: Configuring....
mailSend: setting up incorrect port....
mailSend: Attempt now to send....
mailSend: End of Line
Main: Email Function call finish.
Main: Proccess Complete!
mailComp: Sending of mail failed, will try again in 5 seconds...
mailComp: Retrying...
mailComp: Send successful!
mailComp: End of Line

现在,我放置了错误的端口设置,因此第一封电子邮件失败,并测试第二次是否成功.即使使用正确的端口,页面仍然等待.只有在mailComp函数完成后才会最终发布Page.这是SendAsyn的一些限制吗?

这里有一些代码,不确定这是否有用.


    protected void btnReset_Click(object sender, EventArgs e)
    {
        try
        {
            DataContext db = new DataContext();

            var query = from u in db.Fish
                        where u.Username == txtUsername.Text & u.Email == txtEmail.Text
                        select new { u.Username, u.Email };

            if (query.Count() != 0)
            {


                User user = new User();
                String token = user.requestPasswordReset(txtUsername.Text);
                String URL = Request.Url.AbsoluteUri.ToString() + "?token=" + token;
                String body = "Reseting you password if you \n" + URL + "\n \n ";


                Untilty.SendEmail(txtEmail.Text, "Reseting Password", body);

                litTitle.Text = "Message was sent!";
                litInfo.Text = "Please check your email in a few minuets for further instruction.";
                viewMode(false, false);
            }
            else
            {
                litCannotFindUserWithEmail.Visible = true;
            }


        }
        catch (Exception ex)
        {
            Debug.Write("Main: Exception: " + ex.ToString());
            litInfo.Text = "We are currently having some technically difficulty. Please try  again in a few minuets. If you are still having issue call us at 905344525";
        }
    }



///
public static class Utility

///

    public static void SendEmail(string recipient, string subject, string body)
    {
        MailMessage message = new MailMessage();

        message.To.Add(new MailAddress(recipient));
        message.From = new MailAddress(fromaddress, "Basadur Profile Website");
        message.Subject = subject;
        message.Body = body;

        Send(message);
    }

    private static void Send(MailMessage msg)
    {
        SmtpClient smtp = new SmtpClient();
        smtp.Host = "smtp.gmail.com";
        smtp.Credentials = new System.Net.NetworkCredential(fromaddress, mailpassword);
        smtp.EnableSsl = true;
        Debug.WriteLine("mailSend: setting up incorrect port....");
        smtp.Port = 5872; //incorrect port
        smtp.SendCompleted += new SendCompletedEventHandler(smtp_SendCompleted);

        smtp.SendAsync(msg, msg);

    }

    static void smtp_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
    {
        var msg = (MailMessage)e.UserState;

        if (e.Error != null)
        {
            System.Threading.Thread.Sleep(1000 * 5);

            try
            {
                SmtpClient smtp = new SmtpClient();
                smtp.Host = "smtp.gmail.com";
                smtp.Credentials = new System.Net.NetworkCredential(fromaddress, mailpassword);
                smtp.EnableSsl = true;
                smtp.Port = 587;
                smtp.Send(msg); 
            }
            catch (Exception ex)
            {
                Debug.WriteLine("mailComp: Failed for the second time giving up.");
            }
        }

    }

最佳答案 在.NET 4.5.2中,添加了一种方法,用于在后台调度任务,与任何请求无关:
HostingEnvironment.QueueBackgroundWorkItem().

HostingEnvironment.QueueBackgroundWorkItem()位于System.Web.Hosting命名空间中.

文件中的评论说:

Differs from a normal ThreadPool work item in that ASP.NET can keep
track of how many work items registered through this API are currently
running, and the ASP.NET runtime will try to delay AppDomain shutdown
until these work items have finished executing.

这意味着,您可以以一种即发即弃的方式启动任务,并且在应用程序域回收时不会终止任务.

用法如下:

HostingEnvironment.QueueBackgroundWorkItem(cancellationToken =>
{
    try 
    {
       // do work....
    }
    catch(Exception)
    {
        //make sure nothing can throw in here
    }
});
点赞