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

C# 发送电子邮件后,应用程序使用50%的CPU,c#,.net,email,smtpclient,C#,.net,Email,Smtpclient,我有一个正在使用的应用程序,当我尝试发送电子邮件时,电子邮件成功发送,但应用程序使用50%的CPU直到关闭 下面是导致问题的send方法 public void Send() { if(System.String.IsNullOrEmpty(this.Server)) { throw new PreferenceNotSetException("Server not set"); } if(System.String.IsNullOrEmpty(t

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

下面是导致问题的send方法

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
        }
    }
}
我不知道该怎么做才能使这项工作顺利进行,任何帮助都将不胜感激


谢谢,

这绝对不是对您问题的回答,但它只是一种更简单、更短(我认为更清晰)的重新排列代码的方式的演示:

    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)之外,没有其他功能上的区别。

看到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());              
                    }
    }
}

再想一想,我怀疑你有一个可怕的反病毒系统,它截获了winsock的电话,并在你发送邮件后咀嚼你的邮件

你在开什么车

      System.Net.ServicePointManager.MaxServicePointIdleTime = 1;

这几乎可以肯定是问题的原因。它影响System.Net类使用的内部计时器。我不太清楚它是干什么的,我想这和超时有关。该计时器创建一个线程池线程。更改该值后,计时器将每秒创建1000个线程池线程。很明显,在创建计时器后,将该值设置回原位不会改变计时器。属性的正常值为100000,值1可能从未测试过。

@Tester101,呃,为什么不测试?如果你不知道你的程序在做什么,这是第一个使用的工具。是的,软件调试器通常比使用SO的人更有用。你知道Visual Studio Express是免费的,对吗?还有,你听说过
String.IsNullOrEmpty吗?@Tester101:你在说什么?我怎么能对任何人大发雷霆?我确实帮了你的忙,我告诉你该使用哪个(免费)工具,并告诉你需要调用什么方法来进行比较。“我本可以走得更远,相信我!”约翰·桑德斯:问题不在于你说什么,而在于你怎么说。你的评论给人的印象是浮夸和居高临下,尽管你可能不是有意的。我们中的一些人仍在学习。感谢您的输入。非常感谢,我不熟悉String.IsNullOrEmpty。正如你提到的,在我的情况下,我不能使用SmtpClient。很高兴收到有用的反馈,谢谢。我必须使用System.Net.ServicePointManager.MaxServicePointIdleTime来正确发送电子邮件。如果没有它,电子邮件在很长一段时间内都不会发送,或者直到应用程序关闭。也谢谢你的风格建议,我还在学习,所以很高兴能得到有用的建议。赛门铁克。是的,它确实会弄乱发送的邮件,这就是为什么我不得不弄乱System.Net.ServicePointManager.MaxServicePointIdleTime。这也是我最初的想法之一,但CPU使用率应该会急剧下降,尽管我不能说所有A/V都表现良好(即使是主要品牌)@Tester101:您确实应该尝试禁用Symantec的电子邮件扫描,看看这是否会影响/消除您的体验。感谢您的帮助,我们发现答案是将System.Net.ServicePointManager.MaxServicePointIdleTime设置得太低。如果您还记得的话,实际上,我是第一个建议取消对System.Net.ServicePointManager.MaxServicePointIdleTimeI的更改的人。我必须更改此项以快速发送电子邮件,是否有更好的方法来完成此操作?开始一个新问题,解释您注意到的使您更改此设置的问题。详细说明。将值从1更改为1000,现在一切正常。谢谢你的帮助。