none
Congelamiento de la rutina RRS feed

  • Pregunta

  • Cordial saludo

    estoy comenzando a programar  con Visual Estudio y Tengo un inconveniente en la comunicación con una maquina a la cual debo enviar unos códigos y ella me retorna un +1 ó un +0

    Estoy usando comunicación TCIP con en programa winsock, Cada que le envío un código los datos uno  por uno manualmente el programa funciona pero cuando hago la rutina se bloquea

    En el textBox1 recibo la información y el Textbox2 envió la información.

    Después de haber realizado el enlace con la maquina le doy click en enviar y un botón debe ponerse de color verde pero esto no ocurre, tampoco manda la primera linea de código a la maquina  

    De antemano gracias por su colaboración 

       Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

            TextBox1.Clear()
            If Button2.BackColor = Color.Red Then
                MsgBox(" Primero hay que conectarse ")
            Else
                Button1.BackColor = Color.Green

                TextBox2.Text = "*CLS;*OPC?"
                Cliente.SendData(TextBox2.Text & vbCrLf)
                Do While TextBox1.Text = String.Empty
                Cliente.GetData(TextBox1.Text)
                Loop

                TextBox2.Text = "INIT;*OPC?"
                Cliente.SendData(TextBox2.Text & vbCrLf)
                Do While TextBox1.Text = String.Empty
                Cliente.GetData(TextBox1.Text)
                Loop
             

                 TextBox2.Text = "FETCH?"
                Cliente.SendData(TextBox2.Text & vbCrLf)
               Do While TextBox1.Text = String.Empty
                Cliente.GetData(TextBox1.Text)
                Loop

            End If

        End Sub

     Private Sub Cliente_DataArrival(sender As Object, e As AxMSWinsockLib.DMSWinsockControlEvents_DataArrivalEvent) Handles Cliente.DataArrival
            Cliente.GetData(TextBox1.Text)
                  
        End Sub

    lunes, 11 de junio de 2018 15:55

Respuestas

  • Hola Gasana:

    Ya veo por donde van los tiros. Estas usando mal los textBox, dado que le entregas el código al manejador y no puedes retronarle, a la vista para que cambie cosas en los textbox, porque no dispone de el control.

    Tienes que empezar a utilizar para esto, (existen otras técnicas, pero esta es creo la más fácil), hilos, o lo que te voy a sugerir, utilzar backgroundworker.

    En este caso entregas la ejecución a un "trabajador" en segundo plano y mediante el método reportProgress puedes ir modificando los textbox, que estan en otro contexto de ejecución.

    Te pongo dos ejemplos para que le eches un ojo. No me parecen dificiles de implementar

    http://www.visual-basic-tutorials.com/Tutorials/Controls/BackGroundWorker.htm

    https://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.aspx

    La web esta llena de ejemplos de este uso.

    Ya me contarás como te evoluciona

    Saludos

    jueves, 14 de junio de 2018 15:41

Todas las respuestas

  • Hola Gasana:

    A lo mejor me equivoco mucho, pero así a primera vista, si estas intentando hablar con algo por la red y no lo escuchas, no puedes saber si esta hablando contigo.

    Imaginate que en algún momento que invocas a cliente.getdata, por lo que sea el te esta indicando algo, No lo sabes, y jamás te saldrá del bucle, dado que si no te devuelve un String, textbox1 estará vacio.

    A mi juicio, debes de utilizar un bloque try catch, para cada comunicación con tu cliente externo, dado que simplemente si se corta la comunicación de red, o cualquier otra incidencia que pueda ocurrir, deja el software en espera. Cuando no debiera de ser así. Además de que no sabes lo que ocurre.

    Luego, pones un punto de interrupción en ese método y vas trazando paso a paso, y al menos, es posible, que te devuelva informacíon.

    https://msdn.microsoft.com/es-es/library/y740d9d3.aspx

    Un saludo

    lunes, 11 de junio de 2018 17:35
  • Javi

    Cordial saludo

    En el programa que estoy haciendo después de enviar un código, espero que el sistema me responda con un +0 o un +1 , realice otra prueba cambiando el do loop por el for next para ver como me enviaba los datos  pero el se congela un memento y manda todos los códigos en rafaga ( seguidos uno tras otro sin respetar el for)

    Quiero que el programa envie un codio y esper un tiempo y luego envio otro codigo.

     Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

            'If Button2.BackColor = Color.Red Then
            '    MsgBox(" Primero hay que conectarse ")
            'Else
            Button1.BackColor = Color.Green


            TextBox2.Text = "CONF:OPER:MODE 0;*OPC?"
            Cliente.SendData(TextBox2.Text)

            For T As Integer = 1 To 500000
                T = T + 1
            Next T
       

            TextBox2.Text = "CONF:APPLY;*OPC?"
            Cliente.SendData(TextBox2.Text)
            For T As Integer = 1 To 500000
                T = T + 1
            Next T

            TextBox2.Text = "*STB?"
            Cliente.SendData(TextBox2.Text)
            For T As Integer = 1 To 500000
                T = T + 1
            Next T

            TextBox2.Text = "*CLS;*OPC?"
            Cliente.SendData(TextBox2.Text)
            For T As Integer = 1 To 500000
                T = T + 1
            Next T

        End if

    End Sub


    Voy a probar con el try catch

    Gracias 

    martes, 12 de junio de 2018 15:35
  • Javi 

    No se en que punto del programa me podría servir el Try chatch

    por favor me podría indicar donde lo ubico

    Gracias

    martes, 12 de junio de 2018 19:39
  • Hola Gasana:

    Cuando ejecutas Client.SendData. No es porque este mal, ni bien, sino porque, es la misma idea que cuando abres un fichero tu sabes que esta bien, que esta ahi, y que esta todo genial, pero el sistema de repente te devuelve un IoException. Si no lo controlas, no funciona. A veces es tan simple como que te esta indicando, algo, pero al no escucharlo, no lo sabemos.

    Un saludo

    martes, 12 de junio de 2018 19:57
  • Javi 

    Buena tarde

    Una pregunta  porque cuando comienza la rutina 

      'If Button2.BackColor = Color.Red Then
            '    MsgBox(" Primero hay que conectarse ")
            'Else
            Button1.BackColor = Color.Green

                TextBox2.Text = "*CLS;*OPC?"
                Cliente.SendData(TextBox2.Text & vbCrLf)
                Do While TextBox1.Text = String.Empty
                Cliente.GetData(TextBox1.Text)
                Loop

    No se pone inmediatamente el color verde en el boton1 como si lno pasara por esta linea "aunque si pasa" .  Yo veo que es  después de  haber pasado por todos los códigos enviados que cambia de color el  boton1. puedo ver de que forma están llegando los datos.  A lo que quiero llegar es que me da la impresión es que hay una rutina que tiene el control inclusive cuando hago el paso a paso  

    Gracias por su atención

    martes, 12 de junio de 2018 22:49
  • Javi realice la misma rutina con try  catch

    y no se están dando los retardos que se necesitan  creo que hay que implementar hilos, no se como  

    TextBox1.Clear()

            If Button2.BackColor = Color.Red Then
                MsgBox(" Primero hay que conectarse ")
            Else
                Button1.BackColor = Color.Green
                Try

                    TextBox2.Text = "*CLS;*OPC?"
                    Cliente.SendData(TextBox2.Text & vbCrLf)
                    For T As Integer = 1 To 89500000
                        T = T + 1
                    Next T


                    TextBox2.Text = "*xxxxxxx?"
                    Cliente.SendData(TextBox2.Text & vbCrLf)
                    For T As Integer = 1 To 89500000
                        T = T + 1
                    Next T

                    TextBox2.Text = "*CLS;*OPC?"
                    Cliente.SendData(TextBox2.Text & vbCrLf)
                    For T As Integer = 1 To 89500000
                        T = T + 1
                    Next T


                    TextBox2.Text = "*uyfgyfyuffy"
                    Cliente.SendData(TextBox2.Text & vbCrLf)
                    For T As Integer = 1 To 59500000
                        T = T + 1
                    Next T

                    TextBox2.Text = "*xbhftttttt"
                    Cliente.SendData(TextBox2.Text & vbCrLf)
                    For T As Integer = 1 To 59500000
                        T = T + 1
                    Next T
                Catch ex As Exception
                    MsgBox(ex.Message)
                End Try

            End If

        End Sub

    miércoles, 13 de junio de 2018 0:39
  • Hola. Si necesitas retardos.

    https://msdn.microsoft.com/es-es/library/d00bd51t(v=vs.110).aspx

    Implementar hilos no es lógico desde mi punto de vista.

    Un hilo, no es más que un procesamiento en paralelo de un código. Los hilos no son faciles de controlar, dado que por lógica tienen una vida aparte de nuestro "hilo de ejecución". Y creo, que tu en realidad necesitas lo contrario. Establecer un dialogo con un dispositivo a través de un canal de comunicación.

    Cuando esto lo tengas afinado, lo que si puede ser interesante, es que delegues la comunicación a un hilo o a una task, y tu programa este haciendo lo que tenga que hacer aunque sea nada, y ese otro proceso de comunicación este haciendo lo que tenga que hacer, sin bloquear la interfaz del usuario, de la cual se encarga el hilo principal.

    Un saludo

    miércoles, 13 de junio de 2018 5:35
  • Javi 

    Una pregunta  porque cuando comienza la rutina 

      'If Button2.BackColor = Color.Red Then
            '    MsgBox(" Primero hay que conectarse ")
            'Else
            Button1.BackColor = Color.Green

                TextBox2.Text = "*CLS;*OPC?"
                Cliente.SendData(TextBox2.Text & vbCrLf)
                Do While TextBox1.Text = String.Empty
                Cliente.GetData(TextBox1.Text)
                Loop

    No se pone inmediatamente el color verde en el boton1 como si lno pasara por esta linea "aunque si pasa" .  Yo veo que es  después de  haber pasado por todos los códigos enviados que cambia de color el  boton1. puedo ver de que forma están llegando los datos.  A lo que quiero llegar es que me da la impresión es que hay una rutina que tiene el control inclusive cuando hago el paso a paso  

    Gracias por su atención

    miércoles, 13 de junio de 2018 12:39
  • Hola Gasana:

    Porque el manejador del evento no ha terminado para devolver el control al formulario y pintar la resolución de tu color.

    Imáginate de el funcionamiento de este modo. El manejador que invocó el usuario recoge el control de proceso (yo)....y voy ejecutando lineas....de repente el codigo dice button1.backcolor.... (por tanto algo ha cambiado que alguien tiene que hacer, pero no es el hilo de procesamiento en el que esta ahora.... por tanto le digo a Button1 tio cambia de color....pero yo continuo con mi código (el no se ha pintado), y yo en mí código tengo un problema. El hilo de ejución lo tengo yo y aunque le he dicho que se cambie el color, no le he pasado el testigo, por tanto no hay color.

    Si quieres que te realice eso el modo mas simple es manda ese pintado a un método y con el retorno de ese método que solo pinta en función de ese if....referescas y continuas con el codigo. Si esto no te funciona entonces ya tienes que cambiar cosas más importantes, utilizar hilos o asincronía para los procesos....otra guerra. Primero consigue amarrar esto.

    Saludos

    miércoles, 13 de junio de 2018 13:06
  • lo de pintar el color es lo de menos el problema es que  e utilizado el for next, tyr catch, sleep y en todos los casos el programa que tengo no envia la información de acuerdo a los tiempos que yo establezco

    Despues de enviar una código 

    TextBox2.Text = "*CLS;*OPC?"

    Cliente.SendData(TextBox2.Text & vbCrLf)

    el programa debe esperar un tiempo y enviar el siguiente código  y asi sucesivamente

    Lo que veo esta sucediendo  porque puedo ver como llega la información,  es que el programa se queda bloqueo por un tiempo  y luego envía toda la información en ráfaga incluido poner el botón en verde (un código tras otro sin respetar los tiempos) y termina sin errores.

    como si existiera una programa que tomara  solo el control de los for next, los hiciera todos primero y luego  enviara los códigos. 

    Atento a  sus comentarios

       

    miércoles, 13 de junio de 2018 15:09
  • Hola: Voy a leer lo que yo veo de tu código en cristiano, sin saber como tienes que enviar a esa interfaz la comunicación. A lo mejor, yo desde fuera veo otras cosas que tu no ves, y llegamos a una solución.

      If Button2.BackColor = Color.Red Then
                MsgBox(" Primero hay que conectarse ")
            Else
                Button1.BackColor = Color.Green
                Try
    
    
                    TextBox2.Text = "*CLS;*OPC?"
    /*le mandas al cliente el texto explicito *CLS;*OPC?  */
    /*Anexando el retorno de carro y avance de linea */
                    Cliente.SendData(TextBox2.Text & vbCrLf)
    /*La primera duda, es no tienes que conectarte, el siempre esta a la escucha, no hay que hacer un conect o algo similar primero*/
    /*inicias un bucle. este bucle tarda en recorrerlo en tu máquina 3 segundos, en la mia que tiene un microprocesdor 486 4 minutos 34 segundos */
                    For T As Integer = 1 To 89500000
                        T = T + 1
                    Next T
    /*Nota: Si el cliente de la interfaz requiere de tiempo utiliza thread.sleep(unidad de tiempo en millisecons)*/
    
    /*Le asignas al textBox, cosa que por otra parte podías hacer con una variable local, pero...continuo
    el texto: *xxxxxxx? y le anexas un retorno y avance */
                    TextBox2.Text = "*xxxxxxx?"
                    Cliente.SendData(TextBox2.Text & vbCrLf)
    /*Supongo que sigue a la espera.....*/
    /*Haces otro bucle que dependiendo de la maquina y de sus procesadores, etc resolverá en x unidades de tiempo, siendo imposible, determinar cuantas son */
                    For T As Integer = 1 To 89500000
                        T = T + 1
                    Next T
    /* igual que antes */
                    TextBox2.Text = "*CLS;*OPC?"
                    Cliente.SendData(TextBox2.Text & vbCrLf)
                    For T As Integer = 1 To 89500000
                        T = T + 1
                    Next T
    
    /* idem */
                    TextBox2.Text = "*uyfgyfyuffy"
                    Cliente.SendData(TextBox2.Text & vbCrLf)
                    For T As Integer = 1 To 59500000
                        T = T + 1
                    Next T
    /* idem */
                    TextBox2.Text = "*xbhftttttt"
                    Cliente.SendData(TextBox2.Text & vbCrLf)
                    For T As Integer = 1 To 59500000
                        T = T + 1
                    Next T
    /* no se porque pero yo diría que en Windows Forms MsgBox requiere del método Show. Hace mucho que no toco vb...pero me parece que es así  MsgBox.Show(ex.Message)*/
                Catch ex As Exception
                    MsgBox(ex.Message)
                End Try
    
            End If
    
        End Sub 

    Así desde fuera, lo veo yo

    Haber si te ayuda otra mirada diferente

    miércoles, 13 de junio de 2018 16:03
  • Si el programa se conecta y el equipo esta pendiente de la lleagada de los codigos

      Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Cliente.RemoteHost = "192.168.1.11"
            
            Cliente.RemotePort = "6315"
       
            Cliente.Connect()
        End Sub

        Private Sub Cliente_DataArrival(sender As Object, e As AxMSWinsockLib.DMSWinsockControlEvents_DataArrivalEvent) Handles Cliente.DataArrival
            Cliente.GetData(TextBox1.Text)
                   
        End Sub


        Private Sub AxWinsock1_ConnectEvent(sender As Object, e As EventArgs) Handles Cliente.ConnectEvent
            MsgBox(" Se ha conectado")
            Button2.BackColor = Color.Green
        End Sub

    y vemos lo mismo pero no ocurre lo que vemos, el programa se congela realizando los for next o los thread sleep

    y parece que primero hace esto y después envía los códigos uno tras otro sin respetar los retardos

    sin embargo no se presenta error en el envió de los codigos


      

    miércoles, 13 de junio de 2018 17:37
  • Sacalos de esa rutina y metelos en otra.

    button click..

    rutina llama

    rutina espera

    rutina llama

    rutina espera.

    Haciendo cosas inesperadas a veces aparece el muerto

    miércoles, 13 de junio de 2018 18:15
  • donde rutina llama es el envio y rutina espera hace las pausas. Al hacerlo en rutinas separadas estamos seguros que el CLR no va a encasquetar codigo optimizado y hacer algo por el medio,

    Try cachea ambas rutinas.

    miércoles, 13 de junio de 2018 18:16
  • Gracias  lo voy a reorganizar
    miércoles, 13 de junio de 2018 18:35
  • Javi

    Cordial saludo

    Cambie la rutina y solo cuando entra al MSGBOX se genera el retardo que se necesita, si quito el MSGBOX el programa sigue igual envia toda la información sin respetar los tiempos.

    Que mas se podría hacer que no sea un MSGBOX con entrada para poder controlar el tiempo que se envían los datos

     Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            If Button2.BackColor = Color.Red Then
                MsgBox(" Primero hay que conectarse ")
            Else
                Button1.BackColor = Color.Green
                codigo1()
                Enviar()
                MsgBox("textbox2.text")
                espera()

                codigo2()
                Enviar()
                MsgBox("textbox2.text")
                espera()

                codigo3()
                Enviar()
                MsgBox("textbox2.text")
                espera()

                codigo4()
                Enviar()
                MsgBox("textbox2.text")
                espera()

                codigo5()
                Enviar()
                MsgBox("textbox2.text")
                espera()

                codigo6()
                Enviar()
                MsgBox("textbox2.text")
                espera()

                codigo7()
                Enviar()
                MsgBox("textbox2.text")
                espera()

                codigo8()
                Enviar()
                MsgBox("textbox2.text")
                espera()

                codigo9()
                Enviar()
                MsgBox("textbox2.text")
                espera()

                codigo10()
                Enviar()
                MsgBox("textbox2.text")
                espera()

                codigo11()
                Enviar()
                MsgBox("textbox2.text")
                espera()

                codigo12()
                Enviar()
                MsgBox("textbox2.text")
                espera()

                codigo13()
                Enviar()
                MsgBox("textbox2.text")
                espera()

                codigo14()
                Enviar()
                MsgBox("textbox2.text")
                espera()

                codigo15()
                Enviar()
                MsgBox("textbox2.text")
                espera()
                   End If
        End Sub

     Private Sub codigo1()
            TextBox2.Text = "*CLS;*OPC?"
        End Sub

        Private Sub codigo2()
            TextBox2.Text = "SYST:VERS:DEV?"
        End Sub

        Private Sub codigo3()
            TextBox2.Text = "SENS:X:RANG Auto;*OPC?"
        End Sub

        Private Sub codigo4()
            TextBox2.Text = "SENS:N:RANG Auto;*OPC?"
        End Sub

        Private Sub codigo5()
            TextBox2.Text = "CONF:MEAS:MPER 16;*OPC?"
        End Sub

        Private Sub codigo6()
            TextBox2.Text = "CONF:MEAS:SRAT 80;*OPC?"
        End Sub

        Private Sub codigo7()
            TextBox2.Text = "CONF:MEAS:INT 1;*OPC?"
        End Sub

        Private Sub codigo8()
            TextBox2.Text = "CONF:EN61850:APPID 1;*OPC?"
        End Sub

        Private Sub codigo9()
            TextBox2.Text = "CONF:SYNC:SOUR 0;*OPC?"
        End Sub

        Private Sub codigo10()
            TextBox2.Text = "CONF:SYN"
        End Sub

      Private Sub Enviar()
            Cliente.SendData(TextBox2.Text & vbCrLf)
        End Sub

        Private Sub espera()
            Thread.Sleep(1000)
            TextBox2.Clear()
        End Sub


    jueves, 14 de junio de 2018 12:50
  • Hola Gasana:

    Ya veo por donde van los tiros. Estas usando mal los textBox, dado que le entregas el código al manejador y no puedes retronarle, a la vista para que cambie cosas en los textbox, porque no dispone de el control.

    Tienes que empezar a utilizar para esto, (existen otras técnicas, pero esta es creo la más fácil), hilos, o lo que te voy a sugerir, utilzar backgroundworker.

    En este caso entregas la ejecución a un "trabajador" en segundo plano y mediante el método reportProgress puedes ir modificando los textbox, que estan en otro contexto de ejecución.

    Te pongo dos ejemplos para que le eches un ojo. No me parecen dificiles de implementar

    http://www.visual-basic-tutorials.com/Tutorials/Controls/BackGroundWorker.htm

    https://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.aspx

    La web esta llena de ejemplos de este uso.

    Ya me contarás como te evoluciona

    Saludos

    jueves, 14 de junio de 2018 15:41
  • Además te voy a poner otro artículo muy interesante, para que entiendas porque yo quería que pusieses en el método enviar un try catch.

    https://blogs.msdn.microsoft.com/warnov/2010/09/08/por-qu-los-bloques-try-catch-s-afectan-el-performance/

    Un saludo

    jueves, 14 de junio de 2018 15:43
  • Javi

    Buena tarde Trabaje con el  BackGroundWorker y esta funcionando se envían los comando con un tiempo bien

    ahora quiero quiero quitar el tiempo de retardo y  hacer un rutina que espere un carácter  y si el carácter es el valido continué enviando el siguiente código 

    algo como el programa que envió pero no me esta funcionado se queda en el loop porque no envía mas datos  

      Private Sub Worker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles Worker1.DoWork

            codigo1()                                     ; pongo el código en TextBox2
            Enviar()                                            ; envio el código
            Do                                                    ; espero a que me responda el equipo
            Loop Until TextBox1.Text = "a"             ; cando responda este código "a" sigo con el envió de otro código
            'espera()     
            codigo2()                                                 
            Enviar()
            Do
            Loop Until TextBox1.Text = "b"
            'espera()
            codigo3()

    Mil gracias por su ayuda      


    jueves, 28 de junio de 2018 0:54