1

我正在编写一个通过类 SmtpClient 发送电子邮件的程序。我使用这段代码:

        try
        {
            MailMessage mail = new MailMessage();
            SmtpClient SmtpServer = new SmtpClient("mailSMTP.it");

            mail.From = new MailAddress("address.it");

            mail.Subject = "oggetto";

            mail.IsBodyHtml = true;
            string htmlBody = "someHTML";

            mail.Body = htmlBody;

            SmtpServer.Port = 25;

            SmtpServer.EnableSsl = false;

            foreach (string indirizzo in indirizzi)
            {
                mail.To.Clear();
                mail.To.Add(indirizzo);
                SmtpServer.Send(mail);
                System.Threading.Thread.Sleep(3000);
            }

            MessageBox.Show("e-mail spedite!");

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }

但它只有在我切断“睡眠”线时才有效。为什么?我认为在此过程中休息一下是个好主意。

4

5 回答 5

2

鉴于有一个例外,假设它在调用Send,我建议不要重新使用该MailMessage对象并在循环的每次迭代中创建一个新对象。例如:

        //...
        foreach (string indirizzo in indirizzi)
        {
            string htmlBody = "someHTML";
            MailMessage mail = new MailMessage 
            {
                From = new MailAddress("address.it"),
                Subject = "oggetto",
                IsBodyHtml = true,
                Body = htmlBody,
            };

            mail.To.Clear();
            mail.To.Add(indirizzo);
            SmtpServer.Send(mail);
        }

如果通过“工作”您的意思是您MessageBox在合理的时间内出现......那么原因是因为Sleep在发送所有消息之前阻塞了 UI 线程。例如,如果您尝试发送 10 条消息,UI 将停止 30 秒(3000 毫秒 X 10)。

于 2012-09-22T15:52:56.840 回答
0

我认为你为这个进程定义了新线程,因为如果你写 System.Threading.Thread.Sleep(3000);意味着主线程将休眠 3000 毫秒。

所以,为这个进程创建一个嵌套线程,之后你可以停止/休眠你的线程。

于 2012-09-22T16:12:35.027 回答
0

在我(和其他人)看来,您应该不惜一切代价尝试避免睡眠,通常情况下您最终会得到一个行为奇怪的应用程序(就像您描述的行为一样)。

我会用一个计时器来解决它,该计时器使用索引来确定下一封要发送的邮件。像这样的东西:

    try
    {
        MailMessage mail = new MailMessage();
        SmtpClient SmtpServer = new SmtpClient("mailSMTP.it");

        mail.From = new MailAddress("address.it");

        mail.Subject = "oggetto";

        mail.IsBodyHtml = true;
        string htmlBody = "someHTML";

        mail.Body = htmlBody;

        SmtpServer.Port = 25;

        SmtpServer.EnableSsl = false;

        var index = 0;

        var timer = new System.Threading.Timer((callbackState) =>
            {
                mail.To.Clear();
                mail.To.Add(indirizzi[index]);
                SmtpServer.Send(mail);

                index++;

                if (index < indirizzi.Count)
                  timer.Change(3000, Timeout.Infinite);
                else {
                    timer.Dispose();
                    Invoke(new Action(DisplayAllEmailsSentMessage));
                }
            }, timer, 3000, Timeout.Infinite);

    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }

请注意,您必须使用 Invoke 以任何方式与 Windows 窗体交互,例如显示消息框。这是因为 Threading.Timer 回调在它自己的线程上执行。

您也可以使用 Windows.Forms.Timer,但我自己很少使用它,因为它位于 Windows.Forms 命名空间中,因此仅适用于用 Windows 窗体编写的 UI。

于 2012-09-22T16:13:02.330 回答
0

由于不活动,Smtp 服务器正在断开您的连接。这最有可能释放服务器上的资源。

SmtpClient文档:

如果应用程序希望向同一个 SMTP 服务器发送多条消息,则可以重新使用由 SmtpClient 类的当前实例建立到 SMTP 服务器的连接。这在使用身份验证或加密建立与 SMTP 服务器的连接时特别有用。验证和建立 TLS 会话的过程可能是昂贵的操作。在向同一 SMTP 服务器发送大量电子邮件时,要求为每封邮件重新建立连接可能会对性能产生重大影响。

一般来说,其他响应者说你不应该在发送之间睡觉是正确的。Smtp 服务器应该足够强大,可以处理您可以按顺序发送给它的所有电子邮件。

于 2012-09-22T19:30:03.287 回答
0
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

 class MailSender
    {
        public static int CreateMessageMdp(String destination,String mdp)
        {
            try
            {
                var client = new SmtpClient("smtp.domain.com", 587)
                {
                    Credentials = new NetworkCredential("appgestionali@domain.com", "password"),
                    EnableSsl = true
                };
                DateTime localDate = DateTime.Now;
                string body = "Suite à votre demande de mot de passe le " + localDate.ToString("F") + "\n on vous envoi votre mot de passe est :" + mdp;
                client.Send("appgestionali@domain.com", destination, "Information", body);
            }
            catch (Exception ex)
            {
                MessageBox.Show(""+ ex.GetBaseException());
                return -1;
            }
            return 0;
        }
    }
}
于 2015-11-08T09:49:50.067 回答