In order for this site to work correctly we need to store a small file (called a cookie) on your computer. Most every site in the world does this, however since the 25th of May 2011, by law we have to get your permission first. Please abandon the forum if you disagree.

Para que este foro funcione correctamente es necesario guardar un pequeño fichero (llamado cookie) en su ordenador. La mayoría de los sitios de Internet lo hacen, no obstante desde el 25 de Marzo de 2011 y por ley, necesitamos de su permiso con antelación. Abandone este foro si no está conforme.

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

Foro público de Xailer en español
ddupre
Posts: 301
Joined: Mon Nov 12, 2007 3:53 pm

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

Postby ddupre » Tue May 12, 2020 7:12 pm

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
User avatar
ignacio
Site Admin
Posts: 8656
Joined: Mon Apr 06, 2015 8:00 pm
Location: Madrid, Spain
Contact:

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

Postby ignacio » Tue May 12, 2020 7:31 pm

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
Ignacio Ortiz de Zúñiga
[Equipo de Xailer / Xailer team]
http://www.xailer.com
ddupre
Posts: 301
Joined: Mon Nov 12, 2007 3:53 pm

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

Postby ddupre » Tue May 12, 2020 7:52 pm

Ignacio,
Muchas gracias por la pronta respuesta.

Aplicaré su consejo y le cuanto como me va.

Saludos
ddupre
Posts: 301
Joined: Mon Nov 12, 2007 3:53 pm

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

Postby ddupre » Wed May 13, 2020 8:35 pm

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

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

Return to “Spanish”