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

私の意見(およびの人)では、ほとんどの場合、Sleep を回避するように努める必要があります。多くの場合、アプリケーションが奇妙な動作をすることになります(説明した動作のように)。

インデックスを使用して次に送信するメールを決定するタイマーで解決します。このようなもの:

    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());
    }

メッセージ ボックスを表示するなど、何らかの方法で Windows フォームとやり取りするには、Invoke を使用する必要があることに注意してください。これは、Threading.Timer コールバックが独自のスレッドで実行されるためです。

Windows.Forms.Timer を使用することもできますが、Windows.Forms 名前空間にあり、Windows フォームで記述された UI にのみ適しているため、私自身はめったに使用しません。

于 2012-09-22T16:13:02.330 に答える
0

非アクティブなため、SMTP サーバーが接続を切断しています。これにより、サーバー上のリソースが解放される可能性が高くなります。

SmtpClientのドキュメントから:

アプリケーションが複数のメッセージを同じ SMTP サーバーに送信したい場合、SMTP サーバーへの SmtpClient クラスの現在のインスタンスによって確立された接続を再利用できます。これは、認証または暗号化を使用して SMTP サーバーへの接続を確立する場合に特に役立ちます。TLS セッションを認証および確立するプロセスは、コストのかかる操作になる可能性があります。大量の電子メールを同じ SMTP サーバーに送信するときに各メッセージの接続を再確立する必要があると、パフォーマンスに大きな影響を与える可能性があります。

一般に、他のレスポンダーは、送信の間に寝てはいけないと言っているのは正しいです。Smtp サーバー、送信できるすべての電子メールを順番に処理できるほど堅牢である必要があります。

于 2012-09-22T19:30:03.287 に答える