Debounce (o rebote) para C#
¿Qué es Debounce?
El debounce (o rebote) es una práctica de programación que se utiliza para garantizar que las tareas que consumen mucho tiempo no se activen con tanta frecuencia y que detenga el rendimiento de nuestra aplicación o sitio web.
En palabras fáciles: Con Debounce establecemos un límite (de milisegundos) que debe transcurrir para poder ejecutar algo.
Debouncer.cs
/** | |
* Example: | |
* | |
* public void MouseMove(object sender, EventArgs event) | |
* { | |
* this.debouncer.Debounce(() => this.DoSomeHeavyTask()); | |
* } | |
* | |
*/ | |
namespace ProgramandoSoft.ACodearla.Utils | |
{ | |
using System; | |
using System.Threading; | |
public class Debouncer : IDisposable | |
{ | |
private Thread thread; | |
private volatile Action action; | |
private volatile int delay = 0; | |
private volatile int frequency; | |
public void Debounce(Action action, int delay = 250, int frequency = 10) | |
{ | |
this.action = action; | |
this.delay = delay; | |
this.frequency = frequency; | |
if (this.thread == null) | |
{ | |
this.thread = new Thread(() => this.RunThread()); | |
this.thread.IsBackground = true; | |
this.thread.Start(); | |
} | |
} | |
private void RunThread() | |
{ | |
while (true) | |
{ | |
this.delay -= this.frequency; | |
Thread.Sleep(this.frequency); | |
if (this.delay <= 0 && this.action != null) | |
{ | |
this.action(); | |
this.action = null; | |
} | |
} | |
} | |
public void Dispose() | |
{ | |
if (this.thread != null) | |
{ | |
this.thread.Abort(); | |
this.thread = null; | |
} | |
} | |
} | |
} |
Gist: https://bit.ly/debouncecs
Ejemplo
1. Creamos un nuevo proyecto
2. Renombramos nuestro form principal, y le agregamos dos páneles
3. Pintamos los páneles (opcional), y agregamos algunas label para mostrar los resultados
4. Instanciamos el debouncer, y lo agregamos al dispose del form.
5. Nos suscribimos al evento mouse move de cada panel.
6. Declaramos los contadores, y los incrementamos dentro de los eventos MouseMove.
Como se puede apreciar, utilizamos el método Invoke en el evento MouseMove del panel con Debouncer. Esto es debido a que Debouncer maneja su propio thread, entonces si no actualizamos el Text del label dentro de un método Invoke (para que este se ejecute en el thread del Form), nuestra aplicación fallará.
Comentarios
Publicar un comentario