私はメールのRabbitMQのキューを監視小さなコンソールアプリケーションを書かれています。電子メールがキューにプッシュされると、私のアプリケーションはその電子メールを受け取って処理し、送信します。
コードの下
それは実際に電子メールを送信するもので、私の電子メールサービスのためのコードです。
public class MailService : IMailService
{
private readonly SmtpClient _smtpClient = new SmtpClient();
public void SendEmail(string toEmail, string subject, string body, bool isHtml)
{
var emailMessage = BuildEmailMessage(toEmail.Trim(), subject.Trim(), body, isHtml);
_smtpClient.SendAsync(emailMessage, null);
}
#region Helpers
private static MailMessage BuildEmailMessage(string toEmail, string subject, string body, bool isHtml)
{
const string fromEmailAddress = "[email protected]";
var emailMessage = new MailMessage(fromEmailAddress, toEmail, subject, body) { IsBodyHtml = isHtml };
return emailMessage;
}
#endregion
}
PROBLEM
は私がRabbitMQのキューに2通のメールを持っていた、と私は私のコンソールアプリケーションの消費者を解雇する場合、それは(私はその第一の電子メールを受信した最初のメールを送信した後、次の例外がスローされました私の受信箱)。
非同期呼び出しはすでに進行中です。このメソッドを呼び出すには、完了またはキャンセルする必要があります。
私はいくつかの掘り出し物を見、this threadがこれを得た理由を説明しました。
SendAsyncを呼び出した後、あなたが送信またはSendAsync使用して、別の電子メールメッセージを送信しようとする前に完了するために、電子メールの送信を待機しなければならない:どうやら
SendAsync()
を使用しているため移動するための方法ではありません。
だから、これについてお勧めの方法は何ですか?私はメールごとにSmtpClient
クラスの新しいインスタンスを作成できますが、それは本当に良いアイデアですか?
なぜ最初に 'SendAsync'を使用していますか?ちょうど 'Send'を使用してください。本当に非同期が必要な場合は、コードをリファクタリングして 'await SendMailAsync'を呼び出す必要があります。つまり、呼び出しスタックのすべての部分を非同期にする必要があります。 – mason
@masonあなたは私のコードをそのまま残し、単に '.Send(message)'を使うか、 'using()'ステートメントでそれを囲むべきですか? – Ciwan
'SmtpClient'をフィールドとして保持するのではなく、usingステートメントで囲む方がよいでしょう。しかし、古いAsyncパターンに基づく 'SendAsync'の代わりに' .Send(message) 'を使用してください。 – mason