首页 > 解决方案 > 如何正确处理 SMTP 对象?

问题描述

我有一个循环,如果您将文件放入文件夹中,它会在成功/失败时向您发送电子邮件。我尝试了自动实现 Dispose() 的“使用”语句。

我还尝试了一个“尝试/最终”声明(在这里推荐:https ://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement 。这两个都给了我这个错误:

无法访问已处置的对象。对象名称“system.net.mail.smtpclient”

尝试1:

private int _disposed;
        private readonly string _fromEmail;
        private readonly SmtpClient _client;

public Emailer()
        {
            _disposed = 0;
            _fromEmail = "email";
            _client = new SmtpClient("domain-com.mail.protection.outlook.com", 25)
            {
                EnableSsl = true,
                Credentials = new NetworkCredential(_fromEmail, "password")
            };
        }

public async Task SendEmailAsync(IList<string> to, string subject, string body)
        {
            using (MailMessage mail = new MailMessage())
            {
                mail.From = new MailAddress(_fromEmail);
                foreach (string toEmail in to)
                    mail.To.Add(toEmail);
                
                mail.Subject = subject;
                mail.Body = body;
                mail.IsBodyHtml = true;

                using (SmtpClient smtp = _client)
                {
                    smtp.Credentials = _client.Credentials;
                    smtp.EnableSsl = _client.EnableSsl;
                    await smtp.SendMailAsync(mail);
                }
            }
        }

尝试2:

private int _disposed;
        private readonly string _fromEmail;
        private readonly SmtpClient _client;

public Emailer()
        {
            _disposed = 0;
            _fromEmail = "email";
            _client = new SmtpClient("domain-com.mail.protection.outlook.com", 25)
            {
                EnableSsl = true,
                Credentials = new NetworkCredential(_fromEmail, "password")
            };
        }

public async Task SendEmailAsync(IList<string> to, string subject, string body)
        {
            using (MailMessage mail = new MailMessage())
            {
                mail.From = new MailAddress(_fromEmail);
                foreach (string toEmail in to)
                    mail.To.Add(toEmail);
                
                mail.Subject = subject;
                mail.Body = body;
                mail.IsBodyHtml = true;

                try
                {
                    SmtpClient smtp = _client;
                    smtp.Credentials = _client.Credentials;
                    smtp.EnableSsl = _client.EnableSsl;
                    await smtp.SendMailAsync(mail);
                }
                finally
                {
                    Dispose();
                }
            }
        }

我的 Dispose() 方法

public void Dispose()
        {
            if (Interlocked.CompareExchange(ref _disposed, 1, 0) != 0)
                return;

            _client.Dispose();
        }
    }
}

标签: c#emailsmtp

解决方案


您在第一次调用时处理了一个 Smtp 对象。您需要公开方法来处置 smtp 对象,一旦您的循环完成,调用此方法来处置您的 smtp 对象并摆脱您的 using 语句。

public void DisposeSMTPClient()
{
    _client.Dispose();
}

public async Task SendEmailAsync(IList<string> to, string subject, string body)
        {
            var mail = new MailMessage();
            
                mail.From = new MailAddress(_fromEmail);
                foreach (string toEmail in to)
                    mail.To.Add(toEmail);
                
                mail.Subject = subject;
                mail.Body = body;
                mail.IsBodyHtml = true;

                    await _client.SendMailAsync(mail);
            
        }


DisposeSMTPClient循环结束后调用此函数


推荐阅读