Частичная работа выполняется дважды (ThreadPool.QueueUserWorkItem)

Я создал систему рассылки новостей, которая позволяет мне указать, какие участники должны получать рассылку. Затем я просматриваю список участников, которые соответствуют критериям, и для каждого участника я создаю персонализированное сообщение и отправляю им электронное письмо асинхронно.

Когда я отправляю электронное письмо, я использую 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));
    }
8
задан Andrés Nava - .NET 9 March 2012 в 01:46
поделиться