发送电子邮件后,应用程序使用50%的CPU

时间:2010-11-09 19:21:25

标签: c# .net email smtpclient

我有一个我正在处理的应用程序,当我尝试发送电子邮件时,电子邮件发送成功,但应用程序然后使用50%的CPU直到它关闭。

这是导致问题的发送方法。

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 个答案:

答案 0 :(得分:5)

      System.Net.ServicePointManager.MaxServicePointIdleTime = 1;

这几乎可以肯定是导致问题的原因。它影响System.Net类使用的内部计时器。不完全确定它的作用,我认为与超时有关。该计时器创建一个线程池线程。更改值后,计时器将每秒创建一千个线程池线程。显然设置值不会在创建计时器后更改计时器。该属性的正常值为100000,值1可能从未测试过。

答案 1 :(得分:4)

稳定地看到50%的CPU使用率似乎表明你的两个CPU内核中的一个陷入无限循环。但是,您发布的方法体不能成为该无限循环的来源。我建议您查看代码的其他部分以解决问题。当CPU使用率为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 :(得分:2)

这绝对不是你问题的答案,但它只是展示了一种更简单,更简洁(更清晰,我认为)重新排列代码的方式:

    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)。

答案 3 :(得分:2)

考虑到这一点,我怀疑你有一个可怕的反病毒系统,它们拦截了winsock电话,并在发送后咀嚼你的外发邮件。

你在运行什么A / V?