tutorial progressbar net form ejemplos ejemplo dowork c# winforms backgroundworker

progressbar - dowork c#



Cómo iniciar y detener un trabajador de fondo ejecutando continuamente usando un botón (5)

Digamos que tengo un trabajador de fondo como este:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { while(true) { //Kill zombies } }

¿Cómo puedo hacer que este trabajador de fondo inicie y deje de usar un botón en un WinForm?


Al parar, ¿realmente quieres decir parar o quieres decir pausa? Si te refieres a parar, entonces esto es pan comido. Cree un controlador de evento de clic de botón para el botón que desea que sea responsable de iniciar el trabajador de fondo y un controlador de evento de clic de botón para el responsable de detenerlo. En su botón de inicio, realice una llamada al método de trabajador en segundo plano que activa el evento do_work. Algo como esto:

private void startButton_Click(System.Object sender, System.EventArgs e) { // Start the asynchronous operation. backgroundWorker1.RunWorkerAsync(); }

En su botón de detención, realice una llamada al método que establece el CancelPending del trabajador de fondo como verdadero, como este:

private void cancelAsyncButton_Click(System.Object sender, System.EventArgs e) { // Cancel the asynchronous operation. this.backgroundWorker1.CancelAsync(); }

Ahora no olvide verificar el indicador CancelationPending dentro del doWork de su trabajador de fondo. Algo como esto:

private void KillZombies(BackgroundWorker worker, DoWorkEventArgs e) { while (true) { if (worker.CancellationPending) { e.Cancel = true; } } }

Y tu método doWork:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; KillZombies(worker, e); }

Espero que esto te pueda guiar en la dirección correcta. Algunas lecturas adicionales:

http://msdn.microsoft.com/en-us/library/b2zk6580(v=VS.90).aspx

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

http://msdn.microsoft.com/en-us/library/waw3xexc.aspx


Use el método de cancelación de sincronización .

backgroundworker1.CancelAsync();

En tu ciclo dentro del hilo de trabajo.

if (backgroundWorker.CancellationPending) return;

Esto no ocurre de inmediato.


Tal vez puedas usar un evento manual como este, no depuré esto pero vale la pena intentarlo. Si funciona, no harás que el hilo gire sus ruedas mientras espera

ManualResetEvent run = new ManualResetEvent(true); private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { while(run.WaitOne()) { //Kill zombies } } private void War() { run.Set(); } private void Peace() { run.Reset(); }


No lo he probado, tengo un código en alguna parte en el que tendré que ver exactamente lo que hice, pero algo así es una adaptación de la respuesta de Fredrik:

private bool _performKilling; private object _lockObject = new object(); private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { while(true) { if (_performKilling) { //Kill zombies } else { //We pause until we are woken up so as not to consume cycles Monitor.Wait(_lockObject); } } } private void StartKilling() { _performKilling = true; Monitor.Pulse(_lockObject); } private void StopAllThatKilling() { _performKilling = false; ]

Un ejemplo más completo de este patrón aquí:

https://github.com/AaronLS/CellularAutomataAsNeuralNetwork/blob/fe9e6b950e5e28d2c99350cb8ff3157720555e14/CellLifeGame1/Modeling.cs


Esta es la forma de hacerlo (enlace a respuesta a continuación)