次の場合に使用できます。バッチメール送信のアプリケーションがあるとします。メッセージを作成し(受信者ごとに異なるメッセージ/添付ファイルがあるため、1つのメッセージにまとめることはできません)、たとえば20人の受信者を選択し、[すべて送信]ボタンを押します。送信には、SendAsyncと「プール」からのいくつかのSmtpClientインスタンスを使用します(SmtpClientは、前の呼び出しが完了する前に、1つのインスタンスでSendAsyncを2回呼び出すことを許可しないため)。
高度なロギングを実行する必要があるすべてのSendAsync呼び出しに対して単一のSmtpClientSendCompletedハンドラーがあります。送信の結果、失敗したメッセージの受信者の名前(アドレスまたは添付ファイル)をログに記録しますが、 AsyncCompletedEventArgsはUserStateの助けを借りてのみこの情報を提供できます。したがって、この目的の基本的なパターンは、カスタムユーザー状態オブジェクトを使用することです。したがって、簡略化された例を参照してください。
ハンドラーで必要となるフィールドを含むインターフェース:
public interface IEmailMessageInfo{
string RecipientName {get;set;}
}
非同期状態クラス:
/// <summary>
/// User defined async state for SendEmailAsync method
/// </summary>
public class SendAsyncState {
/// <summary>
/// Contains all info that you need while handling message result
/// </summary>
public IEmailMessageInfo EmailMessageInfo { get; private set; }
public SendAsyncState(IEmailMessageInfo emailMessageInfo) {
EmailMessageInfo = emailMessageInfo;
}
}
メールを送信するためのコードは次のとおりです。
SmtpClient smtpClient = GetSmtpClient(smtpServerAddress);
smtpClient.SendCompleted += SmtpClientSendCompleted;
smtpClient.SendAsync(
GetMailMessage()
new SendAsyncState(new EmailMessageInfo{RecipientName = "Blah-blah"})
);
そして、ハンドラーのコード例:
private void SmtpClientSendCompleted(object sender, AsyncCompletedEventArgs e){
var smtpClient = (SmtpClient) sender;
var userAsyncState = (SendAsyncState) e.UserState;
smtpClient.SendCompleted -= SmtpClientSendCompleted;
if(e.Error != null) {
tracer.ErrorEx(
e.Error,
string.Format("Message sending for \"{0}\" failed.",userAsyncState.EmailMessageInfo.RecipientName)
);
}
// Cleaning up resources
.....
}
詳細が必要な場合はお知らせください。