Tôi có một Parallel.ForEach đang chạy bên trong một Tác vụ. Nó lặp qua một tập hợp các địa chỉ email và gửi một MailMessage đến hàng đợi SMTP, một khi nó được gửi nó cập nhật một bảng trong DB với kết quả.Parallel.ForEach lặp lại các mục trong bộ sưu tập nhiều lần
Tôi có thể thấy trong DB rằng nó gửi MailMessage đến hàng đợi nhiều lần, đôi khi lên đến 6 lần. Đây là mã đơn giản của tôi, bất cứ ai có thể giới thiệu một cách tiếp cận tốt hơn?
Mở nút nhấp chuột, tôi tạo ra một nhiệm vụ mới ...
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.");
}
Điều này tạo ra một nhiệm vụ, mà về cơ bản được một ConcurrentBag thuê bao (lớp tùy chỉnh), lặp trên việc thu thập và gửi một thông điệp ..
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
}
Tôi được cho rằng ConcurrentBag là an toàn chỉ, vì vậy tôi không chắc tại sao nó sẽ lặp lại một số trong bộ sưu tập nhiều lần. Trong số một nghìn, nó sẽ xếp ít nhất 2 tin nhắn cho 10% bộ sưu tập.
Xin cảm ơn,
Greg.
tôi không hiểu tại sao bạn lại sinh ra song song cho một công việc. Tại sao không chỉ làm mà không có nhiệm vụ và gọi broadcastService.BroadcastCampaign() ;? –
Tôi có Task ở đó vì cuối cùng, một khi tôi có công việc bên trong Parallel.ForEach hoạt động hiệu quả, nó sẽ trở thành một dịch vụ Windows với broadcastService mỗi vài giây, nó rõ ràng là cần một số công việc, tôi chỉ đặt nó vào đó để cho bạn thấy nó đang chạy bên trong một Task, không phải đó là mã cuối cùng. – gfyans