C # WinForms aplicación gasto excesivo del procesador Pero no hacer nada extenuante!

StackOverflow https://stackoverflow.com/questions/1244143

  •  12-09-2019
  •  | 
  •  

Pregunta

Tengo un netbook con procesador de 1.20GHz y 1 GB de RAM.

Estoy corriendo una aplicación WinForms C # en el mismo que, en intervalos de 5 minutos, lee cada línea de un archivo de texto y dependiendo de lo que el contenido de esa línea es, o bien se salta o lo escribe en un archivo XML. A veces puede estar procesando alrededor de 2000 líneas.

Cuando se inicia esta tarea, el procesador entra al tope, el uso del 100%. Sin embargo en mi escritorio con procesador 2,40 GHz y 3 GB de RAM es virgen (por razones obvias) ... ¿hay alguna manera en realidad puede reducir drásticamente este problema procesador? El código no es compleja, no soy malo en la codificación o bien y no estoy constantemente abrir el archivo, leer y escribir ... todo está hecho de una sola vez.

Cualquier ayuda muy apreciada!?

Código de ejemplo

*** temporizador .....

#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);
        }
¿Fue útil?

Solución

Utilice un generador de perfiles y / o Monitor de rendimiento y / o \\live.sysinternals.com\tools\procmon.exe y / o ResourceMonitor para determinar lo que está pasando

Otros consejos

Si el proceso de 5 minuto es una tarea en segundo plano, se puede hacer uso de la prioridad del hilo.

aquí .

Si lo hace el procesamiento en un hilo separado, cambiar su contador de tiempo para ser un System.Threading.Timer y utilizar los eventos de devolución de llamada, usted debe ser capaz de establecer una prioridad más baja en ese hilo que el resto de su aplicación.

Dentro de su bucle parseFile, podría intentar añadir un Thread.Sleep y / o un Application.DoEvents () llamar para ver si eso ayuda. Es mejor hacer esto en el análisis está en un hilo independiente, pero al menos se puede probar esta sencilla prueba para ver si ayuda.

Puede ser que los cuadros de mensaje en sus capturas se están ejecutando en problemas entre subprocesos. Prueba a intercambiar hacia fuera para escribir a la salida de rastreo.

En cualquier caso, hemos publicado un programa entero (poco), lo que no le ayudará a obtener asesoramiento específico. Trate borrado código de método - uno a la vez, científicamente - y tratar de obtener el problema que ocurra / parada que se produzcan. Esto le ayudará a localizar el problema y eliminar las partes irrelevantes de su pregunta (tanto para ti como para el SO).

Su modelo de procesamiento por lotes actual se basa - hacer el análisis, y luego procesar los mensajes, y así sucesivamente

.

lo más probable es reducir la sobrecarga de memoria si se cambiara a un enfoque de estilo de LINQ "pull".

Por ejemplo, se podría convertir su método ParseFile() de esta manera:

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

La ventaja es que cada smsmessage puede ser manejado como se genera, en lugar de analizar todos los mensajes a la vez y luego el manejo de todos ellos.

Esto disminuye su sobrecarga de la memoria, que es una de las causas más probables de la diferencia de rendimiento entre el netbook y el escritorio.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top