Я создал систему рассылки новостей, которая позволяет мне указать, какие участники должны получать рассылку. Затем я просматриваю список участников, которые соответствуют критериям, и для каждого участника я создаю персонализированное сообщение и отправляю им электронное письмо асинхронно.
Когда я отправляю электронное письмо, я использую ThreadPool.QueueUserWorkItem
.
По какой-то причине некоторые участники получают электронное письмо дважды. В моем последнем пакете я отправлял только 712 участникам, но в итоге было отправлено 798 сообщений.
Я регистрирую отправленные сообщения и могу сказать, что первые 86 участников получили сообщение дважды. Вот журнал (в порядке отправки сообщений)
No. Member Date
1. 163992 3/8/2012 12:28:13 PM
2. 163993 3/8/2012 12:28:13 PM
...
85. 164469 3/8/2012 12:28:37 PM
86. 163992 3/8/2012 12:28:44 PM
87. 163993 3/8/2012 12:28:44 PM
...
798. 167691 3/8/2012 12:32:36 PM
Каждый участник должен получить информационный бюллетень один раз, однако, как вы можете видеть, участник 163992 получает сообщения №1 и №86; участник 163993 получил сообщения №2 и №87; и так далее.
Следует также отметить, что между отправкой сообщений № 85 и № 86 была 7-секундная задержка.
Я просмотрел код несколько раз и исключил почти весь код как причину этого, за исключением, возможно, ThreadPool.QueueUserWorkItem
.
Я впервые работаю с ThreadPool, поэтому не очень хорошо с ним знаком.Возможно ли иметь какое-то состояние гонки, вызывающее такое поведение?
=== --- Пример кода --- ===
foreach (var recipient in recipientsToEmail)
{
_emailSender.SendMemberRegistrationActivationReminder(eventArgs.Newsletter, eventArgs.RecipientNotificationInfo, previewEmail: string.Empty);
}
public void SendMemberRegistrationActivationReminder(DomainObjects.Newsletters.Newsletter newsletter, DomainObjects.Members.MemberEmailNotificationInfo recipient, string previewEmail)
{
//Build message here .....
//Send the message
this.SendEmailAsync(fromAddress: _settings.WebmasterEmail,
toAddress: previewEmail.IsEmailFormat()
? previewEmail
: recipientNotificationInfo.Email,
subject: emailSubject,
body: completeMessageBody,
memberId: previewEmail.IsEmailFormat()
? null //if this is a preview message, do not mark it as being sent to this member
: (int?)recipientNotificationInfo.RecipientMemberPhotoInfo.Id,
newsletterId: newsletter.Id,
newsletterTypeId: newsletter.NewsletterTypeId,
utmCampaign: utmCampaign,
languageCode: recipientNotificationInfo.LanguageCode);
}
private void SendEmailAsync(string fromAddress, string toAddress, string subject, MultiPartMessageBody body, int? memberId, string utmCampaign, string languageCode, int? newsletterId = null, DomainObjects.Newsletters.NewsletterTypeEnum? newsletterTypeId = null)
{
var urlHelper = UrlHelper();
var viewOnlineUrlFormat = urlHelper.RouteUrl("UtilityEmailRead", new { msgid = "msgid", hash = "hash" });
ThreadPool.QueueUserWorkItem(state => SendEmail(fromAddress, toAddress, subject, body, memberId, newsletterId, newsletterTypeId, utmCampaign, viewOnlineUrlFormat, languageCode));
}