ここでは単純な概念です。これは、MVC 3およびEntity Framework 4を使用して構築されたサイト向けです。ユーザーがサイトに登録すると、電子メールがその電子メールアドレスに送信されます。私は最初にSmtpClient.Send()を使用してこれを実装し、正常に動作しました。それから私は電子メールを非同期的に送信しようとする明るいアイディアを得ました。私が試みた2つの非同期アプローチに関する問題が発生しています。SmtpClient経由で電子メールを非同期に送信する2つの方法、異なる結果
(この未解答のポストから:https://stackoverflow.com/questions/7558582/how-to-dispose-using-smtpclient-send-and-asynccallback):最初の実装
public bool Emailer(){
.
.
.
using (var smtpClient = new SmtpClient())
{
smtpClient.EnableSsl = true;
smtpClient.Host = "smtp.gmail.com";
smtpClient.Port = 587;
smtpClient.UseDefaultCredentials = false;
smtpClient.Credentials = new NetworkCredential("[email protected]", "mypassword");
var sd = new SendEmailDelegate(smtpClient.Send);
var cb = new AsyncCallback(SendEmailResponse);
sd.BeginInvoke(message, cb, sd);
return true;
}
}
private delegate void SendEmailDelegate(System.Net.Mail.MailMessage m);
private static void SendEmailResponse(IAsyncResult ar)
{
try
{
SendEmailDelegate sd = (SendEmailDelegate)(ar.AsyncState);
sd.EndInvoke(ar); // "cannot access a disposed object" errors here
}
catch (Exception e)
{
_logger.WarnException("Error on EndInvoke.", e);
}
}
これは半分の時間を働いていました。残りの半分は、コールバックで「廃棄オブジェクトにアクセスできません」というエラーが表示されます。 (固体評判を持つメンバーから:What are best practices for using SmtpClient, SendAsync and Dispose under .NET 4.0):
次実装
var smtpClient = new SmtpClient();
smtpClient.EnableSsl = true;
smtpClient.Host = "smtp.gmail.com";
smtpClient.Port = 587;
smtpClient.UseDefaultCredentials = false;
smtpClient.Credentials = new NetworkCredential("[email protected]", "mypassword");
smtpClient.SendCompleted += (s, e) =>
{
smtpClient.Dispose();
message.Dispose();
};
smtpClient.SendAsync(message, null);
私はすべてのエラーを取得いけない、この実装では
が、smtpClientデバッグモードで著しく長い遅延(約5秒)があります。 SendAsync()が実行され、非同期に送信されていないと思うようになりました。
質問:
1)「破棄されたオブジェクト」のエラーを引き起こしている第一の方法で間違って何ですか?
2)2番目の実装でメールが非同期に送信されないという問題がありますか? 5秒の遅延は意味がありませんか?
サイトで多数の電子メール(ユーザー登録、オプトインニュースレターなど)の送信をサポートする必要はありませんが、将来的には多数のユーザーが参加する予定ですが、したがって、電子メールを非同期で送信することにしました。
ありがとうございました。
返信いただきありがとうございます。ハンドラが発射する前にオブジェクトが処分されたことがわかりました。また、私は、SmtpClientを削除し、EndInvokeを呼び出さなければならないことを理解しています。 #2のアプローチはこれを達成していますか? –