Page 1 of 1

Técnicas de programación (loop con Cancelar)

Posted: Tue May 12, 2020 7:12 pm
by ddupre
Buenas tardes Foro.
Espero que todos se encuentren bien.

Quisiera pedirles algún consejo para ralizar lo siguiente:
En una aplicación que tengo funcionando, la cual tiene un loop que crea un archivo por segundo durante un tiempo definido y luego de eso se cierra automáticamente. Lo que necesito es ponerle "algo" para que ese loop pueda interrumpirse a mano. He intentado poner un boton en el form, para cancelar, pero no logro el efecto deseado porque el botón queda como "des habilitado" mientras corre el loop, he dejado que el usuario pueda dar click en la cruz de cerrar el formulario, pero a los pocos segundos Windows indica que la aplicación no responde, sin embargo sige funcionando el loop hasta el final.

¿alguien conoce alguna técnica para lograr esto?

Desde ya muchas gracias.
Daniel

Re: Técnicas de programación (loop con Cancelar)

Posted: Tue May 12, 2020 7:31 pm
by ignacio
Buenos días,

Un ejemplo

Code: Select all

METHOD MyHeavyWork()
  ::lStop := .F.
  DO WHILE WhatEverReturnsTrue() .AND. !::lStop
    ...
   ProcessMessages()
  ENDDO
RETUR NIL


Lógicamente lStop es una DATA que tendrá que crear en el formulario

Esto le va a funcionar correctamente, pero tiene importantes implicaciones:
1) El usuario podrá pulsar o editar cualquier control por lo que es necesario DESHABILITAR TODOS LOS CONTROLES menos un botón que tendrá simplemente el siguiente código: ::lStop := .T. ( y a esperar )
2) Otro problema es que el usuario PODRÁ CERRAR el formulario y usted debe de evitarlo. Para ello recomiendo crear otra data de nombre lWorking que pondrá a .T. cuando se inicie el bucle y a falso cuando termine. En el evento OnClose del formulario deberá controlar que ::lWorking está a falso.

Saludos

Re: Técnicas de programación (loop con Cancelar)

Posted: Tue May 12, 2020 7:52 pm
by ddupre
Ignacio,
Muchas gracias por la pronta respuesta.

Aplicaré su consejo y le cuanto como me va.

Saludos

Re: Técnicas de programación (loop con Cancelar)

Posted: Wed May 13, 2020 8:35 pm
by ddupre
Ignacio,

He seguido su ejemplo y aún no he logrado detener el proceso, tal vez sea porque la lógica del mio no es exactamente igual a la del suyo.
Lo particular de mi proceso es que durante el loop, se van mostrando una ProgressBar y un RichEdit con la información de lo que va sucediendo.

Lo otro que tiene de particular es que el comienzo del loop se puede dar por dos motivos, uno porque se lo llama en el evento OnClick de un botón (Iniciar) y dos por un timer que espera 10 segundos antes de ejecutarlo una vez que emieza a correr la aplicación.

Siguiendo su recomendación, cuando la aplicación comienza, aparece des habilitado el boton Detener (en cuyo evento OnClick puse la instrucción ::lStop := .T.) y una linea antes del comienzo del loop, invierto el estado de los dos botones, el oIniciar:lEnable := .F. y oDetener:lEnable := .T., pero lo que sucede es que dicho cambio se da cuando termina el loop, lo que me deja totalmente confundido.

Le agradezco desde ya por la ayuda.
Un saludo
Daniel


Este es el código:

METHOD BtnIniciarClick( oSender ) CLASS TForm1

::Comenzar( oSender )

RETURN Nil

//------------------------------------------------------------------------------

METHOD BtnDetenerClick( oSender ) CLASS TForm1

::lStop := .T.

RETURN Nil

//------------------------------------------------------------------------------

METHOD Comenzar( oSender ) CLASS TForm1

::oBtnAceptar:lEnabled := .F.
::oBtnCancelar:lEnabled := .T.
::oTimer1:lEnabled := .F.
::lWorking := .T.
::ProcesoPrecios()
::ProcesoStock()
::lWorking := .F.

RETURN Nil

//------------------------------------------------------------------------------