Mam Parallel.ForEach działający wewnątrz zadania. Iteruje on nad zbiorem adresów e-mail i wysyła wiadomość MailMessage do kolejki SMTP, po jej wysłaniu aktualizuje tabelę w bazie danych z wynikiem.Parallel.ForEach wielokrotne powtarzanie elementów w kolekcji
Widzę w DB, że wysyła wiadomość MailMessage do kolejki wiele razy, czasami nawet do 6 razy. Oto mój uproszczony kod, czy ktoś może polecić lepsze podejście?
Na kliknięcia przycisku, tworzę nowe zadanie ...
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.");
}
Stwarza to zadanie, które w zasadzie dostaje ConcurrentBag abonentów (niestandardowe klasy), iteracje nad kolekcji i wysyła wiadomość .. .
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
}
ja skłonni uwierzyć, że ConcurrentBag są thread-safe, więc nie jestem pewien, dlaczego byłoby iteracji nad nieco w kolekcji wiele razy. Spośród tysiąca w kolejce pojawią się co najmniej 2 wiadomości dla 10% kolekcji.
Dzięki,
Greg.
Nie rozumiem, dlaczego spawnujesz równoległość w ramach zadania. Czemu po prostu nie obejść się bez zadania i wywołać broadcastService.BroadcastCampaign() ;? –
Mam zadanie tam, ponieważ w końcu, gdy mam pracę wewnątrz Parallel.ForEach działa perperly, stanie się usługą Windows z broadcastService strzelanie co kilka sekund, to oczywiście wymaga trochę pracy, po prostu umieścić go tam, aby pokazać, że działał w zadaniu, a nie, że był to ostatni kod. – gfyans