2009-08-07 4 views
0

나는 1.20Ghz 프로세서 & 1GB 램이 장착 된 넷북을 가지고있다.C# WinForms App Maxing Processor하지만 힘든 일을하지 마십시오!

5 분 간격으로 텍스트 파일의 모든 줄을 읽고 해당 줄의 내용이 무엇인지에 따라 건너 뛰거나 xml 파일에 쓰는 C# WinForms 응용 프로그램을 실행 중입니다. 때로는 약 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

+0

전체 앱을 이메일로 보낼 수 있습니까? (꽤 많은 코드 .....) – Goober

+0

ParseFile() 함수는 어떻게 생겼습니까? –

답변

4

에 무슨 일이 일어나고 있는지 결정하기 위해 프로파일 및/또는 성능 모니터 및/또는 \\live.sysinternals.com\tools\procmon.exe 및/또는 ResourceMonitor를 사용하여
+1

http://www.eqatec.com/tools/profiler – Charlie

+0

@Charlie : 좋은 링크 - dint know를 참조하십시오. 그것에 대해, 시도해야합니다 –

0

ParseFile 루프 내에서 Thread.Sleep 및/또는 Application.DoEvents() 호출을 추가하면 도움이되는지 확인할 수 있습니다. 구문 분석에서이 작업을 수행하는 것이 더 나은 것은 별도의 스레드에 있지만 적어도이 간단한 테스트를 통해 도움이되는지 확인할 수 있습니다.

0

캐치의 메시지 상자가 스레드 간 문제로 실행되고있을 수 있습니다. 트레이스 출력에 쓰기 위해 스와핑을 시도하십시오.

어쨌든 특정 (전체) 프로그램을 게시 했으므로 구체적인 조언을 구하는 데 도움이되지 않습니다. 메서드 본문을 한 번에 하나씩 과학적으로 삭제하고 문제 발생/중단을 시도하십시오. 이렇게하면 문제를 찾고 문제의 관련없는 부분을 제거하는 데 도움이됩니다 (자신과 SO 모두).

+1

MessageBox's 정상적인 조건에서 거기서 사용해서는 안됩니다. 예외가 던져지고 그것에 의해 예외를 던지는 경우에만 매우 배가 고픈 프로세스입니다 ... – Ray

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 대신 한 번 후 처리에서 모든 메시지를 구문 분석, 처리 할 수 ​​있다는 것입니다 그들 모두.

이렇게하면 넷북과 데스크톱의 성능 차이를 일으킬 수있는 가장 큰 원인 중 하나 인 메모리 오버 헤드가 줄어 듭니다.