0

我有一个正在处理的应用程序,当我尝试发送电子邮件时,电子邮件发送成功,但应用程序随后使用 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

4 回答 4

5
      System.Net.ServicePointManager.MaxServicePointIdleTime = 1;

This is almost certainly what causes the problem. It affects an internal timer, used by System.Net classes. Not exactly sure what it does, something to do with timeouts I think. That timer creates a threadpool thread. After you change the value, the timer will create one thousand threadpool threads per second. Clearly setting the value back doesn't change the timer after it was created. The normal value for the property is 100000, a value of 1 was probably never ever tested.

于 2010-11-09T20:25:29.373 回答
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());              
                    }
    }
}
于 2010-11-09T19:57:52.153 回答
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 周围包含 Using 之外,没有其他功能差异(正如您所评论的,这不适用于 Framework 2.0)。

于 2010-11-09T19:55:54.397 回答
2

Thinking about this more, I suspect you have one of those hideous anti-virus systems which has intercepted winsock calls and is chewing on your outgoing mail after you send it.

What A/V are you running?

于 2010-11-09T20:21:17.020 回答