none
cuelgues en aplicacion sencilla??? RRS feed

  • Pregunta

  • Buenas a todos y feliz 2010!!

    Bueno, les explico el problema que me lleva de cabeza y ya no se que tocar mas.

    He creado una pequeña aplicación para enviar el uso de la cpu y la ram disponible a un PIC por puerto serie, para visualizarlo en display. La aplicación va perfecta hasta pasados un par de minutos que se Cuelga.... ya no se que pensar mas, no se si será mi Pc ya que ahora mismo no tengo otro con que provar que tenga puerto serie.

    Les posteo el codigo:
    public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            PerformanceCounter pc;
            PerformanceCounter mem;
            float cpu = 0;
            float ram = 0;
    
            private void Form1_Load(object sender, EventArgs e)
            {
                timer1.Start();
                pc = new PerformanceCounter("Processor", "% Processor Time", "_Total");
                mem = new PerformanceCounter("Memory", "Available Bytes");
                Port.Open();
            }
    
            private void timer1_Tick(object sender, EventArgs e)
            {
                cpu = pc.NextValue();
                ram = mem.NextValue() / 1024 / 1024;
    
                label3.Text = cpu.ToString() + "%";
                label4.Text = ram.ToString() + " MB";
                enviadatos();
            }
    
            private void enviadatos()
            {
                string dato1 = cpu.ToString(); //5
                string dato2 = ram.ToString(); //6
    
    
                while (dato1.Length < 5)
                {
                    dato1 += " ";
                }
                while (dato2.Length < 6)
                {
                    dato1 += " ";
                }
    
                
    
                for (int i = 0; i < 5; i++)
                {
                    Port.Write(dato1[i].ToString());
                    Thread.Sleep(5);
                }
                for (int i = 0; i < 6; i++)
                {
                    Port.Write(dato2[i].ToString());
                    Thread.Sleep(5);
                }
                            
            }
    
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                Port.Close();
            }
        }
    Como veran es algo sencillisimo... Muchas gracias por su atención.
    miércoles, 6 de enero de 2010 12:04

Respuestas

  • hola

    que vendria a ser "Port" es una comunicacion por algun puerto ?


    - has validado si el tiempo que ahs asignado al timer1 no es algo corto por ahi ampliarlo un poco
    recuerda que esta en milisegundos

    - tambien es buena practica deshabilitar el tiemr cuando procesar el evento Tick
    algo asi


    private void timer1_Tick(object sender, EventArgs e)
    {
        timer1.Enable = false;
       
        cpu = pc.NextValue();
        ram = mem.NextValue() / 1024 / 1024;

        label3.Text = cpu.ToString() + "%";
        label4.Text = ram.ToString() + " MB";
        enviadatos();
       
        timer1.Enable = true;
    }


    esto ayuda aq ue cuando se procesa el evento no caiga otra llamada del timer y genere conflictos


    saludos
    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    • Marcado como respuesta tannke miércoles, 6 de enero de 2010 15:42
    miércoles, 6 de enero de 2010 13:44
  • lo que pasa es que segun calculo el método enviadatos() no ha terminado de procesarce cuando ya timer1_Tick() se ha disparado de nuevo...


    por el camino esta parte es mal:

                while (dato2.Length < 6)
                {
                    dato1 += " ";
                }
    Pues logicamente lo que quieres es modificar a dato2 no a dato 1... esta tampoco es la mejor forma de hacerlo...
    para evitarlo puedes intentar hacer algo así y de paso mejorar un poco lo de la concatenacion de espacios:

    dato2 = dato2.PadRight(6,' ');


    tampoco se la razón por la cual escribes cada carácter de a uno :

                for (int i = 0; i < 5; i++)
                {
                    Port.Write(dato1[i].ToString());
                    Thread.Sleep(5);
                }
    pudiendo hacerlo todo de una vez
    Port.Write(dato1);
    Thread.Sleep(50);

    Bien esta es mi propuesta, la cual te permitirá solucionar el problema de que el Tick se dispare cuando aún estas escribiendo, sin entrar a verificar en exceso cual seria el tiempo adecuado, asi que he creado un control con bloqueos.


            PerformanceCounter pc;
            PerformanceCounter mem;
            float cpu = 0;
            float ram = 0;
            private static object lockObject = new object();
    
            private void Form1_Load(object sender, EventArgs e)
            {
                timer1.Start();
                pc = new PerformanceCounter("Processor", "% Processor Time", "_Total");
                mem = new PerformanceCounter("Memory", "Available Bytes");
                Port.WriteTimeout = 200;
                Port.Open();
            }
    
            private void timer1_Tick(object sender, EventArgs e)
            {
                timer1.Enabled = false;
                lock (lockObject)
                {
                    cpu = pc.NextValue();
                    ram = mem.NextValue() / 1024 / 1024;
    
                    label3.Text = cpu.ToString() + "%";
                    label4.Text = ram.ToString() + " MB";
                    enviadatos();
                }
                timer1.Enabled = true;
            }
    
            private void enviadatos()
            {
                lock (lockObject)
                {
                    string dato1 = cpu.ToString(); //5
                    string dato2 = ram.ToString(); //6
    
                    dato1 = dato1.PadRight(5, ' ');
                    dato2 = dato1.PadRight(6, ' ');
    
                    Port.Write(dato1);
                    Thread.Sleep(25);
    
                    Port.Write(dato2);
                    Thread.Sleep(100);
                }            
            }
    
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                Port.Close();
            }


    Atención a estos fragmentos de codigo:

            bool autorizaTimer = true;
            private static object lockObject = new object();

    Port.WriteTimeout = 200;


            private void timer1_Tick(object sender, EventArgs e)
            {
                lock(lockObject)
    { cpu = pc.NextValue(); ram = mem.NextValue() / 1024 / 1024; label3.Text = cpu.ToString() + "%"; label4.Text = ram.ToString() + " MB"; enviadatos(); } }


                lock (lockObject)
                {
                    string dato1 = cpu.ToString(); //5
                    string dato2 = ram.ToString(); //6
    
                    dato1 = dato1.PadRight(5, ' ');
                    dato2 = dato1.PadRight(6, ' ');
    
                    Port.Write(dato1);
                    Thread.Sleep(25);
    
                    Port.Write(dato2);
                    Thread.Sleep(200);
                }


    Colabora con la comunidad, si éste mensaje te ha sido de utilidad, márcalo como respuesta correcta.
    Juan Carlos Ruiz Pacheco
    Ingeniero de Sistemas
    Microsoft MVP C#
    MCP,MCTS,DCE+Platino,OCA,OCP
    Visita Mi Blog C# XNA Sistemas Operativos
    miércoles, 6 de enero de 2010 13:50
    Moderador

Todas las respuestas

  • hola

    que vendria a ser "Port" es una comunicacion por algun puerto ?


    - has validado si el tiempo que ahs asignado al timer1 no es algo corto por ahi ampliarlo un poco
    recuerda que esta en milisegundos

    - tambien es buena practica deshabilitar el tiemr cuando procesar el evento Tick
    algo asi


    private void timer1_Tick(object sender, EventArgs e)
    {
        timer1.Enable = false;
       
        cpu = pc.NextValue();
        ram = mem.NextValue() / 1024 / 1024;

        label3.Text = cpu.ToString() + "%";
        label4.Text = ram.ToString() + " MB";
        enviadatos();
       
        timer1.Enable = true;
    }


    esto ayuda aq ue cuando se procesa el evento no caiga otra llamada del timer y genere conflictos


    saludos
    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    • Marcado como respuesta tannke miércoles, 6 de enero de 2010 15:42
    miércoles, 6 de enero de 2010 13:44
  • lo que pasa es que segun calculo el método enviadatos() no ha terminado de procesarce cuando ya timer1_Tick() se ha disparado de nuevo...


    por el camino esta parte es mal:

                while (dato2.Length < 6)
                {
                    dato1 += " ";
                }
    Pues logicamente lo que quieres es modificar a dato2 no a dato 1... esta tampoco es la mejor forma de hacerlo...
    para evitarlo puedes intentar hacer algo así y de paso mejorar un poco lo de la concatenacion de espacios:

    dato2 = dato2.PadRight(6,' ');


    tampoco se la razón por la cual escribes cada carácter de a uno :

                for (int i = 0; i < 5; i++)
                {
                    Port.Write(dato1[i].ToString());
                    Thread.Sleep(5);
                }
    pudiendo hacerlo todo de una vez
    Port.Write(dato1);
    Thread.Sleep(50);

    Bien esta es mi propuesta, la cual te permitirá solucionar el problema de que el Tick se dispare cuando aún estas escribiendo, sin entrar a verificar en exceso cual seria el tiempo adecuado, asi que he creado un control con bloqueos.


            PerformanceCounter pc;
            PerformanceCounter mem;
            float cpu = 0;
            float ram = 0;
            private static object lockObject = new object();
    
            private void Form1_Load(object sender, EventArgs e)
            {
                timer1.Start();
                pc = new PerformanceCounter("Processor", "% Processor Time", "_Total");
                mem = new PerformanceCounter("Memory", "Available Bytes");
                Port.WriteTimeout = 200;
                Port.Open();
            }
    
            private void timer1_Tick(object sender, EventArgs e)
            {
                timer1.Enabled = false;
                lock (lockObject)
                {
                    cpu = pc.NextValue();
                    ram = mem.NextValue() / 1024 / 1024;
    
                    label3.Text = cpu.ToString() + "%";
                    label4.Text = ram.ToString() + " MB";
                    enviadatos();
                }
                timer1.Enabled = true;
            }
    
            private void enviadatos()
            {
                lock (lockObject)
                {
                    string dato1 = cpu.ToString(); //5
                    string dato2 = ram.ToString(); //6
    
                    dato1 = dato1.PadRight(5, ' ');
                    dato2 = dato1.PadRight(6, ' ');
    
                    Port.Write(dato1);
                    Thread.Sleep(25);
    
                    Port.Write(dato2);
                    Thread.Sleep(100);
                }            
            }
    
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                Port.Close();
            }


    Atención a estos fragmentos de codigo:

            bool autorizaTimer = true;
            private static object lockObject = new object();

    Port.WriteTimeout = 200;


            private void timer1_Tick(object sender, EventArgs e)
            {
                lock(lockObject)
    { cpu = pc.NextValue(); ram = mem.NextValue() / 1024 / 1024; label3.Text = cpu.ToString() + "%"; label4.Text = ram.ToString() + " MB"; enviadatos(); } }


                lock (lockObject)
                {
                    string dato1 = cpu.ToString(); //5
                    string dato2 = ram.ToString(); //6
    
                    dato1 = dato1.PadRight(5, ' ');
                    dato2 = dato1.PadRight(6, ' ');
    
                    Port.Write(dato1);
                    Thread.Sleep(25);
    
                    Port.Write(dato2);
                    Thread.Sleep(200);
                }


    Colabora con la comunidad, si éste mensaje te ha sido de utilidad, márcalo como respuesta correcta.
    Juan Carlos Ruiz Pacheco
    Ingeniero de Sistemas
    Microsoft MVP C#
    MCP,MCTS,DCE+Platino,OCA,OCP
    Visita Mi Blog C# XNA Sistemas Operativos
    miércoles, 6 de enero de 2010 13:50
    Moderador
  • Provado y creo que va bien, ahora os comento que tengo que salir. Muchas gracias a los 2
    miércoles, 6 de enero de 2010 15:48
  • Bueno, os cuento la historia. He hecho lo que me habeis propuesto los 2, lo de parar el timer cuando se dispara y reactivarlo cuando acaba, me extrañaba que pudiera haber sido eso porque el timer lo tenia a 500, incluso lo tuve testeando a 1000. Pero bueno con esto nos curamos con salud. Muchas gracias.

    Tambien he cambiado esos bucles while PadRight(...) que por cierto es una función que desconocía totalmente.

    También implemente lo del lockObject, que ahora mismo no se ni para que siver, en cuanto tenga un momento estudiaré de que va la cosa (disfruto de aprender cosas nuevas con esto).


    Bueno, lo del:
    for (int i = 0; i < 5; i++)
                {
                    Port.Write(dato1[i].ToString());
                    Thread.Sleep(5);
                }
    
    esto lo tengo que dejar asi, ya que el pic lo tengo programado (ahun no se casi nada de Asembly) de manera que cata Byte que recepciono lo envio a su posición en el dispay. Si envio del tirón todo el string, supongo que al pic no le da tiempo a recepcionarlos y enviarlos ya que me salen unas cosas rarisimas en el display.
    Supongo que para solucionar esto tendria que crear algun buffer en el pic o cambiar el protocolo (pero esto ya es otro tema no relacionado con C#)

    Lo dicho, muchas gracias a los dos por molestarse en responder. Saludos

    miércoles, 6 de enero de 2010 20:09