Parallel.ForEach повторяет элементы в коллекции несколько раз

У меня Parallel.ForEach работает внутри задачи. Он выполняет итерацию по набору адресов электронной почты и отправляет сообщение MailMessage в очередь SMTP, после чего оно обновляет таблицу в базе данных с результатом.

Я вижу в базе данных, что сообщение MailMessage отправляется в очередь несколько раз, иногда до 6 раз. Вот мой упрощенный код, может ли кто-нибудь порекомендовать лучший подход?

При нажатии кнопки я создаю новую задачу ...

CampaignManager.Broadcast.BroadcastService broadcastService = new CampaignManager.Broadcast.BroadcastService();

        var task = Task<CampaignManager.Broadcast.Results.Broadcast>.Factory.StartNew(() => { 
            return broadcastService.BroadcastCampaign();
        }, TaskCreationOptions.LongRunning);

        Task.WaitAny(task);

        if (task.Result != null)
        {
            Broadcast.Results.Broadcast broadcastResult = task.Result;
            MessageBox.Show(broadcastResult.BroadcastSent.GroupName + " completed. " + broadcastResult.NumberSuccessful + " sent.");
        }

Это создает задачу, которая в основном получает ConcurrentBag подписчиков (настраиваемый класс), перебирает коллекцию и отправляет сообщение ...

public Results.Broadcast BroadcastCampaign()
{
// Get ConcurrentBag of subscribers
subscribers = broadcast.GetSubscribers();

// Iterate through subscribers and send them a message
Parallel.ForEach(subscribers, subscriber =>
{
    // do some work, send to SMTP queue

    // Add to DB log
});

// return result
}

Я убежден, что ConcurrentBag является потокобезопасным, поэтому я не уверен, почему он будет повторять некоторые в коллекции несколько раз. Из тысячи он будет ставить в очередь минимум 2 сообщения для 10% коллекции.

Спасибо,

Грег.

9
задан gfyans 15 August 2011 в 20:15
поделиться