SmtpClient.SendMailAsync 发送大量邮件时方法挂起
SmtpClient.SendMailAsync method is hanging when sending a big amount of mails
我正在尝试使用 SmtpClient.SendMailAsync 方法发送大量电子邮件。
这是我从简单控制台应用程序调用的测试方法。
static void Main(string[] args)
{
SendMailsOnebyOneAsync().GetAwaiter().GetResult();
}
public static async Task SendMailsOnebyOneAsync()
{
for (int i = 0; i < 1000; i++)
{
try
{
using (SmtpClient sMail = new SmtpClient("XXX"))
{
sMail.DeliveryMethod = SmtpDeliveryMethod.Network;
sMail.UseDefaultCredentials = false;
sMail.Credentials = null;
var fromMailAddress = new MailAddress("XXX");
var toMailAddress = new MailAddress("XXX");
MailMessage message = new MailMessage(fromMailAddress, toMailAddress)
{
Subject = "test"
};
await sMail.SendMailAsync(message);
Console.WriteLine("Sent {0}", i);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
有时该方法会挂起 - 它等待 SendMailAsync,这似乎卡住了但没有 return。
我看到一个相关问题
SmtpClient SendMailAsync sometimes never returns。
但是没有建议对我有用的修复方法。
当我尝试使用同步方法时 SmtpClient.Send 一切正常,应用程序永远不会挂起。
有人知道哪里出了问题吗?
使用一个客户端发送重复的邮件。不断创建和处理许多客户端可能有端口问题。
public static async Task SendMailsOnebyOneAsync() {
using (var sMail = new SmtpClient("XXX")) {
sMail.DeliveryMethod = SmtpDeliveryMethod.Network;
sMail.UseDefaultCredentials = false;
sMail.Credentials = null;
for (int i = 0; i < 1000; i++) {
try {
var fromMailAddress = new MailAddress("XXX");
var toMailAddress = new MailAddress("XXX");
var message = new MailMessage(fromMailAddress, toMailAddress) {
Subject = "test"
};
await sMail.SendMailAsync(message);
Console.WriteLine("Sent {0}", i);
} catch (Exception e) {
Console.WriteLine(e.Message);
}
}
}
}
其次,虽然这可能只是一个例子,但尝试一次发送那么多电子邮件是不合理的。
我的一位同事向我指出 SmtpClient 实际上已经过时,Microsoft 建议不要使用它。
见下文link.
************ Update ***********
我已经尝试按照 link 中的建议使用 MailKit。
对于 non async 和 async 发送,相同的场景与 MailKit 完美配合。
**********************************
- 对于使用 SmtpClient 发送大量电子邮件,我记得建议重复使用相同的连接。
- 我会改变你处理异步的方式。试试 ThreadPool.
附带说明一下,SmtpClient 不支持现代协议。
偶尔用于内部使用和测试的电子邮件仍然可以。
你可以试试 MailKit
我正在尝试使用 SmtpClient.SendMailAsync 方法发送大量电子邮件。 这是我从简单控制台应用程序调用的测试方法。
static void Main(string[] args)
{
SendMailsOnebyOneAsync().GetAwaiter().GetResult();
}
public static async Task SendMailsOnebyOneAsync()
{
for (int i = 0; i < 1000; i++)
{
try
{
using (SmtpClient sMail = new SmtpClient("XXX"))
{
sMail.DeliveryMethod = SmtpDeliveryMethod.Network;
sMail.UseDefaultCredentials = false;
sMail.Credentials = null;
var fromMailAddress = new MailAddress("XXX");
var toMailAddress = new MailAddress("XXX");
MailMessage message = new MailMessage(fromMailAddress, toMailAddress)
{
Subject = "test"
};
await sMail.SendMailAsync(message);
Console.WriteLine("Sent {0}", i);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
有时该方法会挂起 - 它等待 SendMailAsync,这似乎卡住了但没有 return。
我看到一个相关问题 SmtpClient SendMailAsync sometimes never returns。 但是没有建议对我有用的修复方法。
当我尝试使用同步方法时 SmtpClient.Send 一切正常,应用程序永远不会挂起。
有人知道哪里出了问题吗?
使用一个客户端发送重复的邮件。不断创建和处理许多客户端可能有端口问题。
public static async Task SendMailsOnebyOneAsync() {
using (var sMail = new SmtpClient("XXX")) {
sMail.DeliveryMethod = SmtpDeliveryMethod.Network;
sMail.UseDefaultCredentials = false;
sMail.Credentials = null;
for (int i = 0; i < 1000; i++) {
try {
var fromMailAddress = new MailAddress("XXX");
var toMailAddress = new MailAddress("XXX");
var message = new MailMessage(fromMailAddress, toMailAddress) {
Subject = "test"
};
await sMail.SendMailAsync(message);
Console.WriteLine("Sent {0}", i);
} catch (Exception e) {
Console.WriteLine(e.Message);
}
}
}
}
其次,虽然这可能只是一个例子,但尝试一次发送那么多电子邮件是不合理的。
我的一位同事向我指出 SmtpClient 实际上已经过时,Microsoft 建议不要使用它。
见下文link.
************ Update ***********
我已经尝试按照 link 中的建议使用 MailKit。 对于 non async 和 async 发送,相同的场景与 MailKit 完美配合。
**********************************
- 对于使用 SmtpClient 发送大量电子邮件,我记得建议重复使用相同的连接。
- 我会改变你处理异步的方式。试试 ThreadPool.
附带说明一下,SmtpClient 不支持现代协议。
偶尔用于内部使用和测试的电子邮件仍然可以。
你可以试试 MailKit