查得资料:
SmtpClient.SendAsync 方法 
将指定的电子邮件发送到 SMTP 服务器以便传递。此方法不会阻止调用线程,并允许调用方将对象传递给操作完成时调用的方法。可是实际上,我用这个方法,每次都要等到邮件完全发送返回后,才会返回页面。我要的效果是,客户能尽快看到发送结果页(无论成功与否),而不用漫长的等待(发送成功很快,但发送失败时候时间很长,要17s)。
public static class MailSender
    {
        public static string mailStatus = String.Empty;
        public static event EventHandler NotifyCaller;
        public static string _Msg;
        public static int _Enqid;
        public static void SendEmail(enquiries enq, string receiver)
        {
            IEnquiriesService enquiriesService = new EnquiriesServiceImpl();
            _Msg = "";
            _Enqid = Convert.ToInt32(enq.id);
            //内容组装
            ......            //邮件异步发送
            string _receiver = receiver;
            string _sendadd = "[email protected]";
            string _sendname = enq.sendername;
            string _subject = "中国黄页询盘信息";
            string _body = sb.ToString();
            System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage();
            msg.To.Add(receiver);
            msg.From = new MailAddress(_sendadd, _sendname, System.Text.Encoding.UTF8);
            msg.Subject = _subject;
            msg.SubjectEncoding = System.Text.Encoding.UTF8;
            msg.Body = _body;
            msg.BodyEncoding = System.Text.Encoding.UTF8;
            msg.IsBodyHtml = true;
            msg.Priority = MailPriority.High;            SmtpClient client = new SmtpClient();
            client.Credentials = new System.Net.NetworkCredential("[email protected]", "123456");
            client.Host = "mail.insigma.com.cn";
            client.Port = 587;            try
            {
                client.SendCompleted += new SendCompletedEventHandler(client_SendCompleted);
                client.SendAsync(msg,msg.To.ToString());
            }
            catch (SmtpException ex)
            {
                _Msg = ex.Message;
            }
        }
        public static void client_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            String token = (string)e.UserState;
            if (e.Cancelled)
            {
                _Msg = token + " Send canceled.";
            }
            if (e.Error != null)
            {
                _Msg = token + " " + e.Error.ToString() + " ";
            }
            else
            {
                _Msg = ("0");
            }
            IEnquiriesService enquiriesService = new EnquiriesServiceImpl();
            enquiriesService.saveReById(_Msg, _Enqid);
            if (NotifyCaller != null) NotifyCaller(mailStatus, EventArgs.Empty);
        }
    }
主程序调用:public ActionResult saveEnquiries()
        {
            enquiries _enquiries = new JavaScriptSerializer().Deserialize<enquiries>(Server.UrlDecode(Request.Form["enquiries"].ToString()));
            string receiveremail = Request.Form["receiveremail"].ToString();
            int res = 1;
            _enquiries.sendingtime = DateTime.Now;
            enquiriesService.save(_enquiries);
            MailSender.SendEmail(_enquiries, receiveremail);  //在此调用
            return Json(res);
        }

解决方案 »

  1.   

    客户端使用jquery接受:$.post("/common/saveEnquiries.html", { enquiries: jsonEnquiries, receiveremail: receiveremail }, function(data) {
                emaillayer.result(data);
      

  2.   

    既然发送成功很快,那你完全可以设置一个Timeout属性来限定错误所消耗的时间的,如下:
    client.Timeout = 5 * 1000;
    这样虽然不太合适,但具体要看你发送的邮件的内容大小,如果是个大附件,那我没办法控制了,也就是说要看你的一般发送内容大小确定out时间即可。
      

  3.   


    Timeout对于 SendAsync 是无效的,参见MSDN官方说明。
    另外楼主这个问题解决了么?偶也碰到这个问题了,是不是MS的BUG?这个异步名不符其,要等发送完成才会显示ASPX页面,对面访客而言,这个异步跟同步没啥区别了,还有个XX用哦
      

  4.   

    针对c/s 其实这个问题并不影响什么,只是b/s 页面你要考虑好方式,不能等待结果再显示你应该先画发送列表,然后ajax去请求发送并反馈结果。
    例如1   xxxx 发送中....(然后反馈发送结果)
    2   xxxx 已完成
    3   xxxx 发送失败
      

  5.   


    最后还是先记录在数据库, timer定时发送