.NET 4.0에서 SmtpClient, SendAsync 및 Dispose 사용에 대한 모범 사례는 무엇입니까?
특히 SendAsync를 사용하여 호출하는 경우 SmtpClient를 일회용으로 사용할 수 있도록 관리하는 방법에 약간 당황합니다. SendAsync가 완료 될 때까지 Dispose를 호출해서는 안됩니다. 하지만 전화를해야합니다 (예 : "using"사용). 시나리오는 전화를 걸 때 주기적으로 이메일을 발송하는 WCF 서비스입니다. 대부분의 계산은 빠르지 만 전자 메일 전송에는 1 초 정도 걸릴 수 있으므로 비동기가 바람직합니다.
메일을 보낼 때마다 새 SmtpClient를 만들어야합니까? 전체 WCF에 대해 하나를 만들어야합니까? 도움!
업데이트 차이가있는 경우 각 전자 메일은 항상 사용자에게 맞게 사용자 정의됩니다. WCF는 Azure에서 호스팅되며 Gmail은 메일러로 사용됩니다.
참고 : .NET 4.5 SmtpClient는 async awaitable
method를 구현 합니다 SendMailAsync
. 하위 버전의 경우 SendAsync
아래에 설명 된대로 사용하십시오.
IDisposable
가능한 빨리 인스턴스를 폐기해야합니다 . 비동기 호출의 경우 메시지가 전송 된 후 콜백에 있습니다.
var message = new MailMessage("from", "to", "subject", "body"))
var client = new SmtpClient("host");
client.SendCompleted += (s, e) => {
client.Dispose();
message.Dispose();
};
client.SendAsync(message, null);
SendAsync
콜백을 수락하지 않는 것은 약간 성가신 일 입니다.
원래 질문은 .NET 4에 대한 것이었지만 .NET 4.5에서 도움이된다면 SmtpClient는 비동기 대기 가능한 메소드를 구현 SendMailAsync
합니다.
결과적으로 전자 메일을 비동기 적으로 보내는 것은 다음과 같습니다.
public async Task SendEmail(string toEmailAddress, string emailSubject, string emailMessage)
{
using (var message = new MailMessage())
{
message.To.Add(toEmailAddress);
message.Subject = emailSubject;
message.Body = emailMessage;
using (var smtpClient = new SmtpClient())
{
await smtpClient.SendMailAsync(message);
}
}
}
SendAsync 메서드를 사용하지 않는 것이 좋습니다.
일반적으로 IDisposable 객체는 가능한 빨리 폐기해야합니다. 객체에 IDisposable을 구현하는 것은 문제의 클래스가 결정적으로 해제되어야하는 값 비싼 리소스를 보유하고 있다는 사실을 알리기위한 것입니다. 그러나 이러한 리소스를 만드는 데 비용이 많이 들고 이러한 개체를 많이 구성해야하는 경우 한 인스턴스를 메모리에 유지하고 재사용하는 것이 좋습니다 (성능 현명). 차이가 있는지 알 수있는 방법은 한 가지뿐입니다. 프로파일 링하십시오!
다시 : 폐기 및 비동기 : 당신은 using
분명히 사용할 수 없습니다 . 대신 일반적으로 SendCompleted 이벤트에 객체를 배치합니다.
var smtpClient = new SmtpClient();
smtpClient.SendCompleted += (s, e) => smtpClient.Dispose();
smtpClient.SendAsync(...);
좋아, 낡은 질문. 그러나 비슷한 것을 구현해야 할 때이 문제를 발견했습니다. 방금 코드를 공유하고 싶었습니다.
I'm iterating over several SmtpClients to send several mail asynchronously. My solution is similar to TheCodeKing, but I'm disposing the callback object instead. I'm also passing MailMessage as userToken to get it in the SendCompleted event so I can call dispose on that as well. Like this:
foreach (Customer customer in Customers)
{
SmtpClient smtpClient = new SmtpClient(); //SmtpClient configuration out of this scope
MailMessage message = new MailMessage(); //MailMessage configuration out of this scope
smtpClient.SendCompleted += (s, e) =>
{
SmtpClient callbackClient = s as SmtpClient;
MailMessage callbackMailMessage = e.UserState as MailMessage;
callbackClient.Dispose();
callbackMailMessage.Dispose();
};
smtpClient.SendAsync(message, message);
}
You can see why it is particularly important to dispose of SmtpClient by the following comment:
public class SmtpClient : IDisposable
// Summary:
// Sends a QUIT message to the SMTP server, gracefully ends the TCP connection,
// and releases all resources used by the current instance of the System.Net.Mail.SmtpClient
// class.
public void Dispose();
In my scenario sending multiple mails using Gmail without disposing the client, I used to get:
Message: Service not available, closing transmission channel. The server response was: 4.7.0 Temporary System Problem. Try again later (WS). oo3sm17830090pdb.64 - gsmtp
'IT story' 카테고리의 다른 글
Nullable과 함께 DateTime.TryParse를 사용하는 방법 (0) | 2020.08.04 |
---|---|
C #에서 익명 유형의 속성에 액세스하는 방법은 무엇입니까? (0) | 2020.08.04 |
Java에서 SHA-256을 통한 해시 문자열 (0) | 2020.08.04 |
if 문을 사용하여 div가 비어 있는지 확인 (0) | 2020.08.04 |
MySQL 업데이트 쿼리에서 '필드 목록'오류의 알 수없는 열 (0) | 2020.08.03 |