2010-11-09 121 views
0

我有一個正在處理的應用程序,當我嘗試發送電子郵件時,電子郵件發送成功,但應用程序使用50%的CPU,直到它關閉了。發送電子郵件後,應用程序使用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 
     } 
    } 
} 

我不確定該做什麼,做任何幫助,將不勝感激。

感謝,

+0

如果你打破執行,程序在做什麼? – 2010-11-09 19:26:53

+0

@Albin Sunnanbo:不知道我沒有使用IDE,所以沒有調試。 – Tester101 2010-11-09 19:31:58

+3

@ Tester101,爲什麼不呢?如果你不知道你的程序在做什麼,那麼這是第一個可用的工具。 – 2010-11-09 19:37:07

回答

5
 System.Net.ServicePointManager.MaxServicePointIdleTime = 1; 

這幾乎肯定是導致問題的原因。它影響System.Net類使用的內部定時器。不完全確定它的功能,與我認爲的超時有關。該計時器創建一個線程池線程。在您更改該值後,計時器將每秒創建一千個線程池線程。清楚地設置該值不會在創建後更改計時器。該屬性的正常值是100000,值1可能從未測試過。

+0

我不得不更改此選項以使電子郵件快速發送,是否有更好的方法來完成此操作? – Tester101 2010-11-09 20:30:13

+0

開始一個新問題,解釋您注意到的問題的類型,使您更改此設置。詳細。 – 2010-11-09 20:33:21

+0

將值從1更改爲1000,現在一切正常。感謝您的幫助。 – Tester101 2010-11-09 20:40:45

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

+0

謝謝你的輸入,非常感謝,我不熟悉String.IsNullOrEmpty。正如你所說,我不能在我的情況下使用SmtpClient。很高興得到有用的反饋,謝謝。 – Tester101 2010-11-09 20:03:01

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());    
        } 
    } 
} 
+0

我不得不使用System.Net.ServicePointManager.MaxServicePointIdleTime來正確發送電子郵件。沒有它,電子郵件將不會長時間發送,或者直到應用程序關閉。並感謝你的風格建議,我仍然在學習,所以很高興得到有用的建議。 – Tester101 2010-11-09 20:06:14

2

更多這方面的思考,我懷疑你有已經截獲這些可怕的防病毒系統的一個winsock調用並在您發送郵件後咀嚼您的外發郵件。

您正在運行什麼A/V?

+0

賽門鐵克。是的,它確實與外發郵件混淆,這就是爲什麼我不得不惹惱System.Net.ServicePointManager.MaxServicePointIdleTime。 – Tester101 2010-11-09 20:25:02

+0

這也是我的第一個想法,但CPU使用率應該會激增並消退,儘管我不能說所有的A/V都表現良好(甚至是主要品牌)。 – 2010-11-09 20:26:04

+0

@ Tester101:您確實應該嘗試禁用賽門鐵克的電子郵件掃描功能,看看它是否會影響/消除您所遇到的情況。 – 2010-11-09 20:29:20

相關問題