I have a site I manage for a client and they wanted to be able to send out emails to all of their membership. I contacted the host and they suggested writing it in a way that it sends out in batches of 50 or less every minute so the mail server doesn't get overloaded.
That sounds great but the only way I could think of to do this without causing the administrator to have to sit on a page while it sends emails and reloads between each batch was to have a page call an ashx handler which fired up a thread to do the work and the thread is set to sleep after each batch for 60 seconds.
When I run the code from my machine it works fine and completes the entire list of emails. When I run it from the web host, which I don't have access to aside from ftp, it nearly completes but doesn't. Then if I try to hit the ashx page again to finish any that weren't sent, it doesn't do anything. It's like the thread causes something to lock up maybe and keeps additional threads from running.
Here's the code I'm using and I've never used threading before... so, does anyone know why it might be doing this and how to make it work correctly? Do I need to specifically kill the thread after I'm done? If so, how? Thanks.
public void ProcessRequest(HttpContext context)
{
if (context.Request.QueryString["id"].IsValid<int>())
{
campaignId = context.Request.QueryString["id"].To<int>();
var t = new Thread(new ThreadStart(SendEmails))
{
Priority = ThreadPriority.Lowest
};
t.Start();
}
}
private void SendEmails()
{
int currentCount = 0;
BroadcastEmailCampaign campaign = EmailController.GetCampaign(campaignId, false);
List<Member> memberlist = EmailController.GetEmailList(campaign.CampaignId);
var message = new MailMessage
{
Body = campaign.Body,
From = new MailAddress(campaign.SentBy),
IsBodyHtml = true,
Subject = campaign.Subject,
BodyEncoding = Encoding.UTF8
};
//add attachment
if (!string.IsNullOrEmpty(campaign.Attachment) && File.Exists(campaign.Attachment))
{
var attachment = new Attachment(campaign.Attachment);
EmailAttachmentType.SetContentProperites(campaign.Attachment, ref attachment);
message.Attachments.Add(attachment);
}
if (memberlist.Count <= 0)
{
return;
}
bool sendingComplete = false;
EmailController.SetCampaignSendingStatus(true, campaign.CampaignId);
while (sendingComplete == false)
{
message.Bcc.Clear();
message.To.Clear();
message.To.Add(new MailAddress(dummyEmailAddress));
List<Member> emailsToSend = memberlist.Skip(currentCount).Take(takeCount).ToList();
if (emailsToSend.Count <= 0)
{
sendingComplete = true;
EmailController.LogEmailCampaignResult(campaign);
EmailController.SetCampaignSendingStatus(false, campaign.CampaignId);
}
if (!sendingComplete)
{
foreach (Member email in emailsToSend)
{
message.Bcc.Add(new MailAddress(email.Email));
campaign.SentTo.Add(new BroadcastEmailCampaignSentTo
{
MemberId = email.MemberId,
Email = email.Email,
DateSent = DateTime.Now
});
}
EmailController.SendEmail(message);
EmailController.LogEmailsSent(emailsToSend, campaignId);
currentCount += takeCount;
Thread.Sleep(pauseTime);
}
}
}