Вы можете использовать его в следующем случае: представьте, что у вас есть приложение для пакетной отправки электронной почты. Вы составляете сообщение (разные сообщения \ вложения для каждого получателя, поэтому вы не можете объединить его в одно сообщение), выбираете, например, 20 получателей и нажимаете кнопку «Отправить все». Для отправки вы используете SendAsync и несколько экземпляров SmtpClient из «пула» (поскольку SmtpClient не позволяет дважды вызывать SendAsync на одном экземпляре до того, как предыдущий вызов не будет завершен).
У вас есть один SmtpClientSendCompleted обработчик для всех SendAsync вызовов, в которых вы должны выполнить расширенную регистрацию: регистрируйте результаты отправки, имена (адреса или даже вложения) получателей сообщения об ошибках, но 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
.....
}
Пожалуйста, дайте мне знать, если вам нужно больше деталей.