Приложение использует 50% CPU после отправки электронной почты - PullRequest
0 голосов
/ 09 ноября 2010

У меня есть приложение, над которым я работаю, и когда я пытаюсь отправить электронное письмо, оно успешно отправляется, но затем приложение использует 50% ЦП, пока оно не будет закрыто.

Вот метод отправки, который вызывает проблему.

public void Send()
{
    if(System.String.IsNullOrEmpty(this.Server))
    {
        throw new PreferenceNotSetException("Server not set");
    }
    if(System.String.IsNullOrEmpty(this.From))
    {
        throw new PreferenceNotSetException("E-Mail address not set.");
    }
    if(System.String.IsNullOrEmpty(this.To))
    {
        throw new PreferenceNotSetException("Recipients E-Mail address not set.");
    }
    using(System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage(this.From, this.To, this.Subject, this.FormattedText))
    {
        message.IsBodyHtml = true;
        System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient(this.Server);
        client.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
        int temp = System.Net.ServicePointManager.MaxServicePointIdleTime;
        System.Net.ServicePointManager.MaxServicePointIdleTime = 1;
        try 
        {
            client.Send(message);
        }  
        catch(System.Exception ex) 
        {
            //For debugging only.
            System.Windows.Forms.MessageBox.Show(ex.ToString());              
        }
        finally
        {
            System.Net.ServicePointManager.MaxServicePointIdleTime = temp;
            //client.Dispose(); No dispose in .Net 2.0
        }
    }
}

Я не уверен, что делать, чтобы сделать эту работу, любая помощь будет признательна.

Спасибо

Ответы [ 4 ]

5 голосов
/ 09 ноября 2010
      System.Net.ServicePointManager.MaxServicePointIdleTime = 1;

Это почти наверняка вызывает проблему.Влияет на внутренний таймер, используемый классами System.Net.Не совсем уверен, что он делает, я думаю, что-то связано с таймаутамиЭтот таймер создает поток пула потоков.После изменения значения таймер создаст тысячу потоков потоков в секунду.Очевидно, что возврат значения не меняет таймер после его создания.Обычное значение для свойства - 100000, значение 1, вероятно, никогда не проверялось.

4 голосов
/ 09 ноября 2010

Постоянная загрузка 50% процессоров указывает на то, что одно из двух ваших процессорных ядер застряло в бесконечном цикле. Однако опубликованное вами тело метода не может быть источником этого бесконечного цикла. Я предлагаю посмотреть на другие части вашего кода для решения проблемы. Ваше приложение перестает отвечать на запросы, когда загрузка процессора составляет 50%?

Кроме того, почему вы меняете System.Net.ServicePointManager.MaxServicePointIdleTime? Я никогда не видел, чтобы это использовалось, и если вам это не нужно, не используйте его.

Наконец, это скорее субъективная точка зрения на стиль, но я буду утверждать, что вложенные if, которые вы используете, менее понятны и труднее для чтения, чем альтернативные структуры. Я лично считаю, что проверка предварительных условий в верхней части метода, без вложенных условий, намного чище:

public void Send()
{
    if(string.IsNullOrEmpty(this.Server))
    {
        throw new PreferenceNotSetException("Server not set");
    }

    if(string.IsNullOrEmpty(this.From))
    {
        throw new PreferenceNotSetException("E-Mail address not set.");
    }

    if(string.IsNullOrEmpty(this.To))
    {
        throw new PreferenceNotSetException("Recipients E-Mail address not set.");
    }

    using(System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage(this.From, this.To, this.Subject, this.FormattedText))
                { 
                   message.IsBodyHtml = true;
                    System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient(this.Server);
                    client.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;

                    try 
                    {
                        client.Send(message);
                    }  
                    catch(System.Exception ex) 
                    {
                        //Put this in for debugging only.
                        System.Windows.Forms.MessageBox.Show(ex.ToString());              
                    }
    }
}
2 голосов
/ 09 ноября 2010

Думая об этом больше, я подозреваю, что у вас есть одна из тех отвратительных антивирусных систем, которая перехватывает вызовы winsock и проверяет вашу исходящую почту после отправки.

Какой A / V вы используете

2 голосов
/ 09 ноября 2010

Это абсолютно не ответ на ваш вопрос, а просто демонстрация гораздо более простого, короткого, (я думаю, более ясного) способа перестановки кода:

    public void Send()
    {
        if (String.IsNullOrEmpty(Server))
        {
           throw new PreferenceNotSetException("Server not set");
        }
        if (String.IsNullOrEmpty(From))
        {
            throw new PreferenceNotSetException("Sender's E-Mail address not set.");
        }
        if (String.IsNullOrEmpty(To))
        {
            throw new PreferenceNotSetException("Recipient's E-Mail address not set.");
        }
        using (MailMessage message = new MailMessage(From, To, Subject, FormattedText))
        {
            message.IsBodyHtml = true;
            using (SmtpClient client = new SmtpClient(Server))
            {
                client.DeliveryMethod = SmtpDeliveryMethod.Network;
                int temp = ServicePointManager.MaxServicePointIdleTime;
                ServicePointManager.MaxServicePointIdleTime = 1;
                try
                {
                    client.Send(message);
                }
                catch (Exception ex)
                {
                    //Put this in for debugging only.
                    MessageBox.Show(ex.ToString());
                }
                finally
                {
                    ServicePointManager.MaxServicePointIdleTime = temp;
                    //client.Dispose(); No dispose in .Net 2.0
                }
            }
        }
    }

Функциональности нетотличия, кроме включения использования вокруг SmtpClient (как вы уже прокомментировали, это не относится к Framework 2.0).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...