У меня 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% коллекции.
Спасибо,
Грег.