Closed 1257960069 closed 10 months ago
我之前的逻辑是想要共用Client来着 你是发现共用Client是存在线程安全问题吗
2024-01-10 05:09:41 [ERROR] (Hangfire.HttpJob.Support.SmtpOptions) HttpJobDispatcher.InitSmtpClient System.TimeoutException 操作已超时。 在 MailKit.Net.SocketUtils.Connect(String host, Int32 port, IPEndPoint localEndPoint, Int32 timeout, CancellationToken cancellationToken) 在 MailKit.MailService.ConnectNetwork(String host, Int32 port, CancellationToken cancellationToken) 在 MailKit.Net.Smtp.SmtpClient.Connect(String host, Int32 port, SecureSocketOptions options, CancellationToken cancellationToken) 在 Hangfire.HttpJob.Support.SmtpOptions.InitSmtpClient()
我自己写代码测试了下,发现了问题的根本不是是 client.Timeout = 5000; 时间不够. 27秒才连接上,后来才发现,由于自己电脑连接了vpn,导致5秒不够.不连接vpn,2秒就可以了.哎,,,,,,,,,,
尴尬了。。。。那我rollback下
不用rollback,因为我的pr确实修复了你连接失败时未dispose的问题。而我的问题是网络连接超时问题,这种情况下你的代码确实没有释放
我也发现了
using (var client = SmtpOptions.SmtpClient) // 这里有点问题 相当于把单利的SmtpClient给dispose了
{
try
{
client?.Send(mimeMessage);
}
catch (Exception ex)
{
Logger.ErrorException("SmtpClient.SendEmail", ex);
}
finally
{
client?.Disconnect(true);
}
}
那我以你最新的代码为准了哈
一般情况下是不需要共用smtpclient的,只有在短时间发送大量邮件,或发送邮件十分频繁时才需要考虑复用smtpclient。比如blockcollection或channel来实现生产者和消费者解耦,消费者可以多线程
你的旧代码根本不是单例的,因为lazy对象没有被缓存,每次new lazy 在访问value时会调用lazy的初始化工厂方法,方法被多次调用,相当于还是多例
了解了
1.using (var client = SmtpOptions.InitSmtpClient()) 如果InitSmtpClient的内部Connect()方法失败时,由于client的赋值操作还未完成,即使在using()内,也会导致无法被dispose. 2.dispose方法中已经显式调用Disconnect