views:

238

answers:

5

I have a netbook with 1.20Ghz Processor & 1GB Ram.

I'm running a C# WinForms app on it which, at 5 minute intervals, reads every line of a text file and depending on what the content of that line is, either skips it or writes it to an xml file. Sometimes it may be processing about 2000 lines.

When it begins this task, the processor gets maxed out, 100% use. However on my desktop with 2.40Ghz Processor and 3GB Ram it's untouched (for obvious reasons)... is there any way I can actually reduce this processor issue dramatically? The code isn't complex, I'm not bad at coding either and I'm not constantly opening the file, reading and writing... it's all done in one fell swoop.

Any help greatly appreciated!?

Sample Code

***Timer.....

#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);
        }
+4  A: 

Use a profiler and/or Performance Monitor and/or \live.sysinternals.com\tools\procmon.exe and/or ResourceMonitor to determine what's going on

Ruben Bartelink
http://www.eqatec.com/tools/profiler
Charlie
@Charlie: Nice link - dint know about it, must try
Ruben Bartelink
A: 

Inside your ParseFile loop, you could try adding a Thread.Sleep and/or an Application.DoEvents() call to see if that helps. Its better to do this in the parsing is on a seperate thread, but at least you can try this simple test to see if it helps.

SwDevMan81
A: 

Might be that the MessageBoxes in your catches are running into cross-thread problems. Try swapping them out for writing to the trace output.

In any case, you've posted an entire (little) program, which will not help you get specific advice. Try deleting method bodies -- one at a time, scientifically -- and try to get the problem to occur/stop occurring. This will help you to locate the problem and eliminate the irrelevant parts of your question (both for yourself and for SO).

Yar
MessageBox`s should not be used there under normal conditions. Only if exception was thrown and throwing exception by it self is a very resource hungry process...
Ray
+1  A: 

If the 5 minute process is a background task, you can make use of Thread Priority.

MSDN here.

If you do the processing on a separate thread, change your timer to be a System.Threading.Timer and use callback events, you should be able to set a lower priority on that thread than the rest of your application.

TreeUK
A: 

Your current processing model is batch based - do the parsing, then process the messages, and so on.

You'll likely reduce the memory overhead if you switched to a Linq style "pull" approach.

For example, you could convert your ParseFile() method in this way:

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;
        }
    }
}

The advantage is that each SmsMessage can be handled as it is generated, instead of parsing all of the messages at once and then handling all of them.

This lowers your memory overhead, which is one of the most likely causes for the performance difference between your netbook and your desktop.

Bevan