C # WinForms приложение максимизирует процессор, но не делает ничего напряженного! - PullRequest
0 голосов
/ 07 августа 2009

У меня нетбук с процессором 1,20 ГГц и оперативной памятью 1 ГБ.

Я запускаю на нем приложение C # WinForms, которое с 5-минутными интервалами читает каждую строку текстового файла и, в зависимости от содержимого этой строки, либо пропускает ее, либо записывает в файл XML. Иногда он может обрабатывать около 2000 строк.

Когда он начинает эту задачу, процессор получает максимальную отдачу, 100% использования. Однако на моем настольном компьютере с процессором 2,40 ГГц и оперативной памятью 3 ГБ он не тронут (по понятным причинам) ... есть ли какой-нибудь способ реально уменьшить проблему с процессором? Код не сложен, я тоже неплох в кодировании, и я не постоянно открываю файл, читаю и пишу ... все это делается одним махом.

Любая помощь с благодарностью!?

Пример кода

*** Таймер .....

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

Ответы [ 5 ]

4 голосов
/ 07 августа 2009

Используйте профилировщик и / или системный монитор и / или \\live.sysinternals.com\tools\procmon.exe и / или ResourceMonitor, чтобы определить, что происходит

1 голос
/ 07 августа 2009

Если 5-минутный процесс является фоновой задачей, вы можете использовать Приоритет потока.

MSDN здесь .

Если вы выполняете обработку в отдельном потоке, меняете таймер на System.Threading.Timer и используете события обратного вызова, вы сможете установить более низкий приоритет для этого потока, чем для остальной части вашего приложения. *

0 голосов
/ 08 августа 2009

Ваша текущая модель обработки основана на пакетной обработке - выполните синтаксический анализ, затем обработайте сообщения и т. Д.

Скорее всего, вы сократите накладные расходы памяти, если переключитесь на "тяговый" подход в стиле 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 может обрабатываться по мере его создания, вместо того, чтобы анализировать все сообщения сразу, а затем обрабатывать их все.

Это снижает нагрузку на память, что является одной из наиболее вероятных причин разницы в производительности между вашим нетбуком и настольным компьютером.

0 голосов
/ 07 августа 2009

Возможно, что MessageBoxes в ваших перехватах сталкиваются с проблемами между потоками. Попробуйте поменять их для записи в вывод трассировки.

В любом случае вы разместили целую (маленькую) программу, которая не поможет вам получить конкретный совет. Попробуйте удалить тела методов - по одному, с научной точки зрения - и попытаться заставить проблему возникать / прекращать возникновение. Это поможет вам найти проблему и устранить не относящиеся к делу части вашего вопроса (как для себя, так и для SO).

0 голосов
/ 07 августа 2009

Внутри цикла ParseFile вы можете попробовать добавить Thread.Sleep и / или Application.DoEvents () , чтобы посмотреть, поможет ли это. Лучше сделать это при разборе в отдельном потоке, но, по крайней мере, вы можете попробовать этот простой тест, чтобы увидеть, помогает ли он.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...