Domanda

Ho un netbook con processore 1.20Ghz e 1GB di RAM.

Sono in esecuzione di un C # WinForms app su di esso che, ad intervalli di 5 minuti, legge ogni riga di un file di testo e, a seconda di ciò che il contenuto di tale linea è, o salta o si scrive in un file XML. A volte può essere in corso l'elaborazione di circa 2000 linee.

Quando si inizia questa operazione, il processore viene raggiunto il massimo, l'utilizzo al 100%. Comunque sul mio desktop con 2,40 GHz del processore e 3GB di RAM è intatto (per ovvie ragioni) ... c'è un modo posso effettivamente ridurre drasticamente questo problema processore? Il codice non è complessa, io non sono affatto male codifica sia e non sto costantemente l'apertura del file, leggere e scrivere ... è tutto fatto in un colpo solo.

Qualsiasi aiuto molto apprezzato!?

Codice di esempio

*** 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);
        }
È stato utile?

Soluzione

Utilizzare un profiler e / o Performance Monitor e / o \\live.sysinternals.com\tools\procmon.exe e / o ResourceMonitor per determinare cosa sta succedendo

Altri suggerimenti

Se il processo di 5 minuti è un compito background, è possibile fare uso di Priorità thread.

qui .

Se si fa l'elaborazione su un thread separato, modificare il timer per essere uno System.Threading.Timer e utilizzare gli eventi di callback, si dovrebbe essere in grado di impostare una priorità più bassa su quel thread rispetto al resto della vostra applicazione.

All'interno del vostro ciclo ParseFile, si potrebbe provare ad aggiungere un Thread.Sleep e / o un Application.DoEvents () chiamare per vedere se questo aiuta. La sua migliore per fare questo nel parsing è su un thread separato, ma almeno si può provare questo semplice test per vedere se aiuta.

Potrebbe essere che le MessageBox in vostri fermi sono in esecuzione in problemi cross-thread. Provale sostituendo per la scrittura di traccia.

In ogni caso, che hai postato un intero programma (poco), che non vi aiuterà a ottenere una consulenza specifica. Prova cancellazione corpi di metodo - uno alla volta, scientificamente - e cercare di ottenere il problema si verifichi / stop che si verificano. Questo vi aiuterà a localizzare il problema ed eliminare le parti irrilevanti della sua domanda (sia per te e per SO).

Il tuo modello di elaborazione attuale si basa in lotti - fare il parsing, poi elaborare i messaggi, e così via

.

È probabile che riduce l'overhead di memoria se si è passati a un approccio stile Linq "pull".

Per esempio, è possibile convertire il vostro metodo di ParseFile() in questo modo:

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

Il vantaggio è che ogni smsmessage può essere gestita come viene generato, invece di parsing tutti i messaggi in una volta e poi trattare tutti loro.

Questo riduce il sovraccarico della memoria, che è una delle cause più probabili per la differenza di prestazioni tra il netbook e il desktop.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top