2009-08-07 67 views
0

我有一個上網本與1.20Ghz處理器& 1GB公羊。C#WinForms應用程序Maxing處理器,但沒有什麼費勁!

我正在運行一個C#WinForms應用程序,它以5分鐘的時間間隔讀取文本文件的每一行,並根據該行的內容跳過它或將其寫入xml文件。有時可能會處理大約2000行。

當它開始執行此任務時,處理器將最大化,100%使用。然而,在我的臺式機上配備2.40Ghz處理器和3GB內存的情況下(原因很明顯)......有什麼辦法可以顯着減少這個處理器問題嗎?代碼並不複雜,我也沒有編寫代碼,而且我也沒有經常打開文件,閱讀和寫作......這一切都是一舉完成的。

任何幫助非常感謝!?

示例代碼

***定時器.....

#region Timers Setup 

      aTimer.Tick += new EventHandler(OnTimedEvent); 
      aTimer.Interval = 60000; 
      aTimer.Enabled = true; 
      aTimer.Start(); 
      radioButton60Mins.Checked = true; 

      #endregion Timers Setup 


private void OnTimedEvent(object source, EventArgs e) 
     { 
      string msgLoggerMessage = "Checking For New Messages " + DateTime.Now; 
      listBoxActivityLog.Items.Add(msgLoggerMessage); 
      MessageLogger messageLogger = new MessageLogger(); 
      messageLogger.LogMessage(msgLoggerMessage); 

      if (radioButton1Min.Checked) 
      { 
       aTimer.Interval = 60000; 
      } 
      if (radioButton60Mins.Checked) 
      { 
       aTimer.Interval = 3600000; 
      } 
      if (radioButton5Mins.Checked) 
      { 
       aTimer.Interval = 300000; 
      } 

      // split the file into a list of sms messages 
      List<SmsMessage> messages = smsPar.ParseFile(smsPar.CopyFile()); 

      // sanitize the list to get rid of stuff we don't want 
      smsPar.SanitizeSmsMessageList(messages); 

      ApplyAppropriateColoursToRecSMSListinDGV(); 
     } 

public List<SmsMessage> ParseFile(string filePath) 
     { 
      List<SmsMessage> list = new List<SmsMessage>(); 
      using (StreamReader file = new StreamReader(filePath)) 
      { 
       string line; 
       while ((line = file.ReadLine()) != null) 
       { 
        var sms = ParseLine(line); 
        list.Add(sms); 
       } 
      } 
      return list; 
     } 

     public SmsMessage ParseLine(string line) 
     { 
      string[] words = line.Split(','); 

      for (int i = 0; i < words.Length; i++) 
      { 

       words[i] = words[i].Trim('"'); 
      } 
      SmsMessage msg = new SmsMessage(); 
      msg.Number = int.Parse(words[0]); 
      msg.MobNumber = words[1]; 
      msg.Message = words[4]; 
      msg.FollowedUp = "Unassigned"; 
      msg.Outcome = string.Empty; 

      try 
      { 

       //DateTime Conversion!!! 
       string[] splitWords = words[2].Split('/'); 
       string year = splitWords[0].Replace("09", "20" + splitWords[0]); 
       string dateString = splitWords[2] + "/" + splitWords[1] + "/" + year; 
       string timeString = words[3]; 
       string wholeDT = dateString + " " + timeString; 
       DateTime dateTime = DateTime.Parse(wholeDT); 
       msg.Date = dateTime; 

      } 
      catch (Exception e) 
      { 
       MessageBox.Show(e.ToString()); 
       Application.Exit(); 
      } 
      return msg; 
     } 

     public void SanitizeSmsMessageList(List<SmsMessage> list) 
     { 
      // strip out unwanted messages 
      // list.Remove(some_message); etc... 
      List<SmsMessage> remove = new List<SmsMessage>(); 
      foreach (SmsMessage message in list) 
      { 
       if (message.Number > 1) 
       { 
        remove.Add(message); 
       } 
      } 
      foreach (SmsMessage msg in remove) 
      { 
       list.Remove(msg); 
      } 
      //Fire Received messages to xml doc 
      ParseSmsToXMLDB(list); 
} 

public void ParseSmsToXMLDB(List<SmsMessage> list) 
     { 
      try 
      { 
       if (File.Exists(WriteDirectory + SaveName)) 
       { 
        xmlE.AddXMLElement(list, WriteDirectory + SaveName); 
       } 
       else 
       { 
        xmlE.CreateNewXML(WriteDirectory + SaveName); 
        xmlE.AddXMLElement(list, WriteDirectory + SaveName); 
       } 
      } 
      catch (Exception e) 
      { 
       MessageBox.Show(e.ToString()); 
       Application.Exit(); 
      } 
     } 

public void CreateNewXML(string writeDir) 
     { 
      try 
      { 
       XElement Database = new XElement("Database"); 
       Database.Save(writeDir); 
      } 
      catch (Exception e) 
      { 
       MessageBox.Show(e.ToString()); 
      } 
     } 

     public void AddXMLElement(List<SmsMessage> messages, string writeDir) 
     { 
      try 
      { 
       XElement Database = XElement.Load(writeDir); 
       foreach (SmsMessage msg in messages) 
       { 
        if (!DoesExist(msg.MobNumber, writeDir)) 
        { 
         Database.Add(new XElement("SMS", 
           new XElement("Number", msg.MobNumber), 
           new XElement("DateTime", msg.Date), 
           new XElement("Message", msg.Message), 
           new XElement("FollowedUpBy", msg.FollowedUp), 
           new XElement("Outcome", msg.Outcome), 
         new XElement("Quantity", msg.Quantity), 
         new XElement("Points", msg.Points))); 

         EventNotify.SendNotification("A New Message Has Arrived!", msg.MobNumber); 

        } 
       } 
       Database.Save(writeDir); 
       EventNotify.UpdateDataGridView(); 
       EventNotify.UpdateStatisticsDB(); 
      } 
      catch (Exception e) 
      { 
       MessageBox.Show(e.ToString()); 
      } 
     } 

public bool DoesExist(string number, string writeDir) 
     { 
      XElement main = XElement.Load(writeDir); 
      return main.Descendants("Number") 
         .Any(element => element.Value == number); 
     } 
+1

你能提供代碼示例嗎? – Ray 2009-08-07 11:00:17

+0

我可以通過電子郵件向你發送整個應用程序壓縮? (相當多的代碼.....) – Goober 2009-08-07 11:05:16

+0

ParseFile()函數的外觀如何? – 2009-08-07 11:14:14

回答

4

使用分析器和/或性能監視器和/或\\live.sysinternals.com\tools\procmon.exe和/或ResourceMonitor以確定發生了什麼事情

+1

http://www.eqatec.com/tools/profiler – Charlie 2009-08-07 11:21:45

+0

@Charlie:尼斯鏈接 - 知道力德關於它,必須嘗試 – 2009-08-07 11:27:30

0

在您的ParseFile循環中,您可以嘗試添加Thread.Sleep和/或 Application.DoEvents()調用以查看是否有幫助。在解析過程中更好的做法是在單獨的線程中進行,但至少您可以嘗試這個簡單的測試以查看是否有幫助。

0

可能是因爲您的catch中的MessageBox正在運行到跨線程問題。嘗試交換它們以寫入跟蹤輸出。

無論如何,你已經發布了一個完整的(小)程序,它不會幫助你得到具體的建議。嘗試刪除方法體 - 一次一個,科學地 - 並試圖讓問題發生/停止發生。這將幫助您找到問題並消除問題中不相關的部分(無論是針對您自己還是針對SO)。

+1

正常情況下不應該在那裏使用MessageBox。只有當異常被拋出並拋出異常時,它纔是一個非常耗資源的過程。 – Ray 2009-08-07 11:55:06

1

如果5分鐘的過程是後臺任務,則可以使用線程優先級。

MSDN here

如果你在一個單獨的線程上進行處理,將你的計時器改爲System.Threading.Timer並使用回調事件,那麼你應該能夠在該線程上設置比應用其餘部分更低的優先級。

0

您當前的處理模型是基於批處理的 - 執行解析,然後處理消息,等等。

如果切換到Linq風格的「拉」方法,您可能會減少內存開銷。

例如,您可以轉換在這樣您ParseFile()方法:

public IEnmerable<SmsMessage> ParseFile(string filePath) 
{ 
    using (StreamReader file = new StreamReader(filePath)) 
    { 
     string line; 
     while ((line = file.ReadLine()) != null) 
     { 
      var sms = ParseLine(line); 
      yield return sms; 
     } 
    } 
} 

的好處是因爲它產生的每個SmsMessage可以處理的,而不是分析所有的郵件一次,然後處理,他們全部。

這降低了您的內存開銷,這是您的上網本和桌面之間性能差異的最可能原因之一。

相關問題