4

System.Net.Mail.SmtpClient が自分自身に同じメッセージを送信するのを見て、いくつかのテスト コードを書きました。

int numClients = 10;
List<SmtpClient> mailClients = new List<SmtpClient>();
for (int i = 0; i < numClients; i++) {
    mailClients.Add(new SmtpClient(smtpHost));
}

MailMessage msg = new MailMessage("myAddress@eg.com", "myAddress@eg.com", "test message", "" );
foreach (SmtpClient c in mailClients) {
    c.SendAsync(msg, null);
}

「n - 1」メッセージしか受信しないことを除いて、これは問題なく実行されます。つまり、10 通のメッセージを送信しても、受信トレイには 9 通しか届きません。50 を送信すると、49 しか受信しません。

注: ブロッキング送信を使用するようにコードを変更すると、常に適切な数のメッセージが受信されます。例えば

foreach (SmtpClient c in mailClients) {
    c.Send(msg);
} 

何か案は?

4

1 に答える 1

3

役立つかもしれないいくつかの観察事項を次に示します。

  • SmtpClient を 1 つだけ作成します。
  • 代わりに複数のメッセージを作成してください。
  • SmtpClient は IDisposable を実装します。を使用してラップします。
  • MailMessage は IDisposable も実装しています。

すべてが同じ SMTP サーバーをラップする複数の SmtpClient インスタンスでバグ/問題が発生している可能性があります。単一のインスタンスを使用すると、問題が解決する場合があります。

アップデート

MSDN によると:

SendAsync を呼び出した後、Send または SendAsync を使用して別の電子メール メッセージを送信する前に、電子メールの送信が完了するまで待つ必要があります。

http://msdn.microsoft.com/en-us/library/x5x13z6h.aspx

したがって、状況を考えると、Send よりも SendAsync を使用する利点はほとんどありません。前の SendAsync が完了するのを待たないため、ループが何かを踏んでいる可能性があります。

ここにいくつかの考えがあります:

  • 大量のメールを送信する場合、SendAsync は Send とほぼ同じように動作します。送信を使用するだけです。
  • 並行送信が必要な場合は、Producer/Consumer パターンを使用します。1 つ (または複数) の生成スレッドが送信するキューに内容をダンプし、複数の消費スレッドがそれぞれ 1 つの SmtpClient を使用してメッセージを送信します。このパターンは、BlockingCollection で驚くほど簡単に実装できます。MSDN の例を参照してください http://msdn.microsoft.com/en-us/library/dd267312.aspx
  • 十分な数のスレッドを使用すると、SMTP サーバーがボトルネックになります。過負荷になっているときは注意してください。
于 2012-10-09T21:11:36.607 に答える