Исключение ThreadPool и памяти (BTStackServer) - .NET - PullRequest
1 голос
/ 14 марта 2012

В продолжение моей проблемы здесь я создал тестовое приложение, которое использует потоки ThreadPool для отправки электронных писем. Вот код, который я использую.

        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);
        }

Для меньших чисел (10k, 50k) они отлично работают, но как только я увеличу число до 200k (что является моей целью), я получу это исключение:

enter image description here

Он создал около 186 тыс. Электронных писем, прежде чем выдал это исключение.

Я предполагаю, что это не исключение, вызванное нехваткой места на диске (так как я храню все электронные письма локально в C:\temp\testemails, а потому что в RAM было мало (?). Как подсказывает this пользователь , я использовал семафоры, чтобы ограничить их 10k, но все равно столкнулся с той же проблемой. Вот код для того, у кого семафоры.

    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);
        }
    }

Это тоже вызвало исключение, но я вижу все 200 тыс. Писем в папке. Я определенно могу использовать try catch и грациозно выйти, если произойдет это исключение, но как бы я мог предотвратить это в первую очередь.

Ответы [ 2 ]

1 голос
/ 14 марта 2012

Попробуйте избавиться от объекта SmtpClient, обернув его с помощью блока, или явно вызвав dispose ().

0 голосов
/ 14 марта 2012

Попробуйте уменьшить 10000 до 1000 для конструктора SemaphoreSlim.

...