1

In continuation with my problem here, I created a test app that uses ThreadPool threads to send emails. Here's the code I am using.

        protected void btnSend_Click(object sender, EventArgs e)
        {
            EmailInfo em = new EmailInfo { Body = "Test", FromEmail = "test@test.com", Subject = "Test Email", To = "test@test.com" };
//txtNumEmails is a textbox where I can enter number of emails to send
            for (int i = 0; i < Convert.ToInt32(this.txtNumEmails.Text); i++)
            {
                bool bResult = ThreadPool.QueueUserWorkItem(new WaitCallback(EmailNow), em);
            }

        }


        public void EmailNow(object emailInfo) // Email Info object
        {
            EmailInfo em = emailInfo as EmailInfo;

            SmtpClient client = new SmtpClient("localhost");
            client.UseDefaultCredentials = true; 

            client.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
            client.PickupDirectoryLocation = @"C:\temp\testemails\";

            MailMessage m = new MailMessage();
            m.To.Add(new MailAddress(em.To));
            m.Body = em.Body;
            m.IsBodyHtml = false;
            m.From = new MailAddress(em.FromEmail);
            m.Subject = em.Subject;

            client.Send(m);
        }

For smaller numbers (10k, 50k) they work great, but once I increase the number to 200k (which is my target), I got this exception:

enter image description here

It created about 186k emails before it threw this exception.

I am assuming this is not the exception caused due to lack of disk space (since i am storing all the emails locally in C:\temp\testemails but because it was low in RAM(?). As suggested by a this user, I used semaphores to limit them to 10k, but still ran in to the same issue. Here's the code for the one with semaphores.

    protected void Button1_Click(object sender, EventArgs e)
    {
        EmailInfo em = new EmailInfo { Body = "Test", FromEmail = "test@test.com", Subject = "Test Email", To = "test@test.com" };
        var semaphore = new SemaphoreSlim(10000, 10000);

        for (int i = 0; i < Convert.ToInt32(this.txtNumEmails.Text); i++)
        {
            semaphore.Wait();
            bool bResult = ThreadPool.QueueUserWorkItem( (state) => { 
                try 
                {           
                    EmailNow(em);
                }
                catch (Exception)
                {

                    throw;
                }
                finally
                {
                             semaphore.Release();
                }
            },  null);
        }
    }

This one threw an exception as well but I see all 200k emails in the folder. I can definitely use try catch and gracefully exit if this exception occurs, but how would I prevent this from happening in the first place.

Community
  • 1
  • 1
Nick
  • 7,475
  • 18
  • 77
  • 128
  • Whoa...that is no ordinary error. Fatal crashes like that are usually caused by a bug in the CLR, misbehaving unmanaged code, incorrectly using unmanaged code, etc. I second Deepansh suggestion and try disposing that `SmtpClient` object. Other than that you will need to get the crash report and examine the stack trace for clues. – Brian Gideon Mar 14 '12 at 02:20

2 Answers2

1

Try disposing SmtpClient object by either wrapping inside using block or calling dispose() explicitly.

Deepansh Gupta
  • 593
  • 4
  • 9
0

Try reducing the 10000 to 1000 for the SemaphoreSlim constructor.

matthewk
  • 1,841
  • 17
  • 31