Principales respuestas
Salir de un bucle for al pulsar un boton

Pregunta
-
Buenas noches,
tengo un proyectos con 2 clases, form1.cs y funciones.cs.
La cuestión es que en funciones.cs, tengo un bucle for dentro de una función, y en form1 tengo un botón que quiero que cuando se haga click se rompa el bucle. Lo estoy intentando un una variable buleana y break, pero no consigo hacerlo.
Lo he conseguido declarando la variable en el form1 así: public static bool verd = true; y luego dentro del for hago: if (verd == false) { break; }, pero no me gusta declarar así la variable.
¿Como puedo lograr que al hacer click en el botón, cambie el valor de la variable de la otra clase?
Muchas gracias.
Respuestas
-
Lo que quieres hacer es más complicado de lo que parece. Necesitarás utilizar programación en multi-hilo, porque de lo contrario el formulario queda "congelado" mientras se está ejecutando el bucle, y por lo tanto el click del botón no se procesa hasta que el bucle ha terminado (y por lo tanto no te sirve para interrumpirlo).
Una alternativa sencilla es meter una llamada a Application.DoEvents() dentro del bucle. Esto permite que se "libere" el control una vez por cada iteración del bucle y se procese el click en ese momento. Otra alternativa sería usar un BackgroundWorker para ejecutar la función que contiene el bucle. Si sigues esta última vía, el propio BackGroundWorker tiene la funcionalidad de pasar una variable indicando que quieres interrumpir la operación, por lo que no necesitas declararla por separado.
Pero si sigues la primera vía, entonces es válido lo que has hecho de daclarar la variable como public static bool verd. Desde la otra clase, se accede a ella mediante if (!form1.verd) break;
Nótese que para acceder a la variable estática hay que anteponerle el nombre de la clase en la que se declaró.
- Marcado como respuesta Bulldovi domingo, 31 de agosto de 2014 15:37
-
Podrías ver algo así
using System; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { private Funciones Func; public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { ((Button)sender).Enabled = false; Func = new Funciones(); Func.Cancelar = false; Func.CicloInfinito(); Func = null; ((Button)sender).Enabled = true; } private void button2_Click(object sender, EventArgs e) { if (Func != null) Func.Cancelar = true; } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { if (Func != null) Func.Cancelar = true; } } public class Funciones { public bool Cancelar { get; set; } public void CicloInfinito() { for (; !Cancelar; Application.DoEvents()) { // evita consumir todo el tiempo de procesador // puedes quitarla si quieres que consuma todo el ancho de banda posible System.Threading.Thread.Sleep(5); } } } }
[W]
- Marcado como respuesta Bulldovi domingo, 31 de agosto de 2014 15:43
Todas las respuestas
-
Lo que quieres hacer es más complicado de lo que parece. Necesitarás utilizar programación en multi-hilo, porque de lo contrario el formulario queda "congelado" mientras se está ejecutando el bucle, y por lo tanto el click del botón no se procesa hasta que el bucle ha terminado (y por lo tanto no te sirve para interrumpirlo).
Una alternativa sencilla es meter una llamada a Application.DoEvents() dentro del bucle. Esto permite que se "libere" el control una vez por cada iteración del bucle y se procese el click en ese momento. Otra alternativa sería usar un BackgroundWorker para ejecutar la función que contiene el bucle. Si sigues esta última vía, el propio BackGroundWorker tiene la funcionalidad de pasar una variable indicando que quieres interrumpir la operación, por lo que no necesitas declararla por separado.
Pero si sigues la primera vía, entonces es válido lo que has hecho de daclarar la variable como public static bool verd. Desde la otra clase, se accede a ella mediante if (!form1.verd) break;
Nótese que para acceder a la variable estática hay que anteponerle el nombre de la clase en la que se declaró.
- Marcado como respuesta Bulldovi domingo, 31 de agosto de 2014 15:37
-
Podrías ver algo así
using System; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { private Funciones Func; public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { ((Button)sender).Enabled = false; Func = new Funciones(); Func.Cancelar = false; Func.CicloInfinito(); Func = null; ((Button)sender).Enabled = true; } private void button2_Click(object sender, EventArgs e) { if (Func != null) Func.Cancelar = true; } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { if (Func != null) Func.Cancelar = true; } } public class Funciones { public bool Cancelar { get; set; } public void CicloInfinito() { for (; !Cancelar; Application.DoEvents()) { // evita consumir todo el tiempo de procesador // puedes quitarla si quieres que consuma todo el ancho de banda posible System.Threading.Thread.Sleep(5); } } } }
[W]
- Marcado como respuesta Bulldovi domingo, 31 de agosto de 2014 15:43
-
Lo que quieres hacer es más complicado de lo que parece. Necesitarás utilizar programación en multi-hilo, porque de lo contrario el formulario queda "congelado" mientras se está ejecutando el bucle, y por lo tanto el click del botón no se procesa hasta que el bucle ha terminado (y por lo tanto no te sirve para interrumpirlo).
Una alternativa sencilla es meter una llamada a Application.DoEvents() dentro del bucle. Esto permite que se "libere" el control una vez por cada iteración del bucle y se procese el click en ese momento. Otra alternativa sería usar un BackgroundWorker para ejecutar la función que contiene el bucle. Si sigues esta última vía, el propio BackGroundWorker tiene la funcionalidad de pasar una variable indicando que quieres interrumpir la operación, por lo que no necesitas declararla por separado.
Pero si sigues la primera vía, entonces es válido lo que has hecho de daclarar la variable como public static bool verd. Desde la otra clase, se accede a ella mediante if (!form1.verd) break;
Nótese que para acceder a la variable estática hay que anteponerle el nombre de la clase en la que se declaró.
Muchas gracias. Así lo tengo, pero aún no lo he probado. No obstante, quiero mirar la alternativa que propones.
Saludos,
-
Podrías ver algo así
using System; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { private Funciones Func; public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { ((Button)sender).Enabled = false; Func = new Funciones(); Func.Cancelar = false; Func.CicloInfinito(); Func = null; ((Button)sender).Enabled = true; } private void button2_Click(object sender, EventArgs e) { if (Func != null) Func.Cancelar = true; } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { if (Func != null) Func.Cancelar = true; } } public class Funciones { public bool Cancelar { get; set; } public void CicloInfinito() { for (; !Cancelar; Application.DoEvents()) { // evita consumir todo el tiempo de procesador // puedes quitarla si quieres que consuma todo el ancho de banda posible System.Threading.Thread.Sleep(5); } } } }
[W]
Precisamente estoy mirando una alternativa que se me ha ocurrido con las propiedades get set.
No informé que el lenguaje era c#, de echo creo que no puse la pregunta en el subforo apropiado.
Nunca he visto un for en c# con puntos y comas......., perdona si es obvio, pero....¿es c# tu código?
Y muchas gracias
-
-
Nunca he visto un for en c# con puntos y comas
Es muy común en todos los lenguajes derivados del C: C++, C#, java, javascript...
La sintaxis es esta:
for (operación inicial; condición de iteración; instrucción al iterar) {...}
Lo más frecuente es encontrarse un bucle de este tipo:
for (i=0; i<N; i++) {...}
que es el típico bucle que ejecuta N iteraciones contándolas con la variable i.
Pero jugando con las tres expesiones se pueden lograr comportamientos más sofisticados; por ejemplo, este bucle recorre un rango de fechas:
for (DateTime f = fechaInicial; f<dechaFinal; f=f.AddDays(1)) {...}
Cualquiera de las tres expresiones se puede omitir, dejando solo el punto y coma. Por ejemplo, esto es un bucle infinito: for (;;){...}. Equivale a while(true) {...}.
-
-