Usuario
Aplicación se queda congelada (Timer)

Pregunta
-
Hola que tal les comento mi caso:
Realicé una aplicación que utiliza varios Timer (para ser más exacto 3) que se apagan y se prenden cada cierto tiempo, uno de ellos esta constantemente prendido lo cargo en el load del Form principal con su propiedad enabled = true, el detalle es que después de un tiempo digamos horas esta ya no responde y se queda congelada y no responde.
La función de esta aplicación es que recibe datos por medio del puerto serial y de un protocolo de comunicación del cual arroja ciertos datos, les pongo un trozo de código para que me orienten acerca de este problema.
Private Sub tmrEntradas_Timer()
Call fnRecorrerEntradas
End Sub
Public Function fnRecorrerEntradas()
Dim c As Integer
For c = 0 To 24 Step 1
If c >= 24 And GBLEstatusTorreta(GBLCiclo).Torreta = 1 Then
c = 0
GBLEstatusTorreta(GBLCiclo).Torreta = GBLEstatusTorreta(GBLCiclo).Torreta + 1
tmrEntradas.Enabled = False
tmrEstatus.Enabled = True
Exit Function
ElseIf c >= 17 And GBLEstatusTorreta(GBLCiclo).Torreta = 2 Then
c = 0
GBLEstatusTorreta(GBLCiclo).Torreta = 1
countProgress.Caption = ""
tmrEstatus.Enabled = True
tmrEntradas.Enabled = False
Exit Function
End If
Call sbEntradas(c)
Call fnDetenerTiempoDos(GBLTiempo)
Call fnDetenerTiempo(GBLTiempoDos)
Next c
End Function
Private Sub sbEntradas(ByVal i As Integer)
Dim sintciclo As Integer
Dim chksum As Integer
Dim j As Byte
Dim indx As Byte
If i >= 24 Then
i = 0
End If
GBLTipo = "ENTRADA"
protocolo__TX(0) = &H1
protocolo__TX(1) = CByte(GBLEstatusTorreta(GBLCiclo).Torreta)
protocolo__TX(2) = &H0
protocolo__TX(3) = &H3C
protocolo__TX(4) = i 'entrada que se quiere leer
For j = 5 To 19 Step 1
protocolo__TX(j) = 0
Next j
chksum = 0
For indx = 0 To 19 Step 1
chksum = chksum + protocolo__TX(indx)
Next indx
chksum = chksum And 255
chksum = chksum Xor 255
chksum = chksum + 1
protocolo__TX(20) = CByte(chksum And &HFF)
'Envia los datos por el puerto serial
For indx = 0 To 20 Step 1
MSComm1.Output = Chr(protocolo__TX(indx))
Next indx
End Sub
Public Function fnDetenerTiempo(ByVal TicksEsperando As Long)
Dim TicksIniciales As Long
TicksIniciales = GetTickCount() + TicksEsperando
Do While TicksIniciales > GetTickCount()
DoEvents
Loop
End Function
Public Function fnDetenerTiempoDos(ByVal TicksEsperando As Long)
Dim TicksIniciales As Long
TicksIniciales = GetTickCount() + TicksEsperando
Do While TicksIniciales > GetTickCount()
Loop
End Function
Las propiedad interval del Timer es de 1000 y Enabled= False (la propiedad enabled la enciendo en el load ),La variable GBLtiempo = 1000"" GBLtiempoDos= 300Me comentaban que le detalle podría ser porque tengo declaradas variables detro del metodo del Timer, porque según esto esas variables no se destruyen en tiempo de ejecución o cuando abandona el evento Timer y me recomendarón aplicar un Nothing y declarar las variables en la clase osea fuera del metodo Timer.Espero me puedan ayudar de antemano mil Gracias!!
Todas las respuestas
-
Saludos
Puede ser que tu Procedimiento fnRecorrerentradas demore mas de un segundo y antes que termine el timer lanza una segunda llamada, es posible que después de un tiempo las llamadas se interpongan, si ocurre esto, imagino que el puerto serial se mantiene ocupado cada vez más tiempo en procesar las solicitudes de la cola, mientras tanto el timer sigue enviado nuevas peticiones cada nuevo segundo. Es una idea.
Saludos
CarloCF -
Saludos
Puede ser que tu Procedimiento fnRecorrerentradas demore mas de un segundo y antes que termine el timer lanza una segunda llamada, es posible que después de un tiempo las llamadas se interpongan, si ocurre esto, imagino que el puerto serial se mantiene ocupado cada vez más tiempo en procesar las solicitudes de la cola, mientras tanto el timer sigue enviado nuevas peticiones cada nuevo segundo. Es una idea.
Saludos
CarloCFOk me parece bién la perspectiva de lo que pueda estar causando este problema, pero como sería la solución? le doy más interval al Timer? o le doy más segundos a las funciones encargadas de detener el tiempo para el envio de datos?. alguna idea que puedas sugerir? agradezco tu ayuda.
GRACIAS!
-
Imagino (no revisé el código que colocas) que utilizas los temporizadores para revisar el objeto comm_control.
Mejor utiliza el evento oncomm, que se dispara cuando llega data. Por mas que he buscado, no he encontrado información clara, sin embargo, lo utilizo para comunicarme con un modem sms sin problema.
Te pego aquí código que tomé de un ejemplo (no recuerdo de donde).
Private Sub GsmComm_OnComm()
Debug.Print GsmComm.Input
Select Case GSMComm.CommEvent
'"Mensajes relativos a sucesos
Case comEvReceive
'RecibirCom
Case comEvSend
evmsg = "Por ahora no hago nada"
Case comEvCTS
evmsg = "Cambio detectado en CTS"
Case comEvDSR
evmsg = "Cambio detectado en DSR"
Case comEvCD
evmsg = "Cambio detectado en DCD"
Case comEvRing
evmsg = "El teléfono está sonando"
Case comEvEOF
evmsg = "Fin de fichero"
'"Mensajes de error
Case comBreak
evmsg = "Interrupción detectada"
Case comCTSTO
ERMsg = "Tiempo para CTS sobrepasado"
Case comDSRTO
ERMsg = "Tiempo para DSR sobrepasado"
Case comFrame
evmsg = "Error de transmisión (encuadre)"
Case comOverrun
ERMsg = "Error de sobrescritura"
Case comCDTO
ERMsg = "Tiempo para DCD sobrepasado"
Case comRxOver
ERMsg = "Buffer de recepción lleno"
Case comRxParity
evmsg = "Error de paridad"
Case comTxFull
ERMsg = "Buffer de transmisión lleno"
Case Else
ERMsg = "Error o suceso desconocido"
End Select
End Sub
-
Hola
En este punto creo que debes probar y ver si resulta. Adicionalmente guarracuco te sugiere un evento y el codigo de muestra. Yo haria tanteo y error para ver por donde se decanta el problema con las correcciones. Esperamos tus noticias
Saludos
CarloCF
-
claro guarracuco eso es lo que hago en el On_Common hay es donde hago ciertas operaciones para recibir la información las funciones de detención del tiempo las hago después que mando el protocolo de comunicación para que de esta manera se vayan los comandos de uno en uno y después me responde de la misma manera con un protocolo parecido.
CommEvent = ComEvReceive estos metodos los utilizo para cuando reciba el dato después actue sobre los mismos.
-
Bueno CarloCF me comentarón que podía dividir mi aplicación en 2 partes lo que pasa es que en una parte del protocolo de comunicación tengo que recibir 23 datos uno en uno, después con esos datos yo los manipulo y hago updates a una BD en MySQL, pero esto se hace con los 23 datos osea estamos hablando de demasiados updates en un segundo y aparte hace unas comparaciones para enviar e-mails si esa información es correspondiente con la de la BD, el envio de correos lo hago por SMTP.
Me comentabas anteriomente que quiza la función que tenia demoraba más tiempo que 1 segundo y si tenias razón daba un tick cada 23 ocasiones entonces opte por meter el protocolo de comunicación directo en el Timer en el evento Tick y ahora si por cada petición que hace se realiza un tick y aumenta esa variable, el detalle es lo que te comento que estoy sobresaturando las funciones y mi aplicación con los updates y compraraciones.
Me propusierón hacer esto: que generara un .exe que solo actualizara(por medio de store procedure´s y cosas demás) por un cierto tiempo(10 minutos ) después de pasar ese tiempo la aplicación se cierra, cuando se cierra se abre el otro .exe que solo se encargará de obtener los registros que me arroja el protocolo de comunicación una vez que termine de vaciar la información se cerrará y vuelvo a abrir el .exe que se encarga de actualizar los datos en tiempo real, para vaciar los datos no toma menos de 3 minutos asi que por ese lado pienso que la información estaria casi actual de lo que esta sucediendo.
los comandos para la obtención de datos y lectura de los mimos son diferentes que el comando que me manda la información en tiempo real, así que por ese lado no hay problema.
Nota: me comentarón también que esto lo podia realizar por medio del programador de tareas de windows.
Espero y puedan comentar acerca de esta propuesta.!
Saludos y Gracias!
-
Nerk10, si sigues lo comentado por CarloCF de almacenar en un buffer o arreglo o tablita lo que vá llegando? y un proceso paralelo (otra exe) realiza las operaciones? la cuestión está (al menos para mí) que solo tu tienes un panorama claro del proceso.