¿Hay un nombre para el error "Más eventos de lo esperado"?

7

¿Existe un nombre para una familia de errores , que se debe a la suposición de que el usuario generará solo 1 evento durante la ejecución del controlador?

El ejemplo más simple es: animación activada por clic, que puede ejecutar varias copias de sí misma, si el usuario hace clic varias veces rápidamente.

    
pregunta c69 17.11.2011 - 12:21

4 respuestas

9

Lo que has descrito es un excelente ejemplo de ...

Condición de la carrera

Una condición de carrera (aplicable tanto a la electrónica como a la programación) es cuando "el la salida y / o el resultado del proceso dependen de forma inesperada y crítica de la secuencia o el tiempo de otros eventos ".

También has descrito un problema con ...

Reentrancy

En general, los métodos que pueden llamarse a sí mismos de manera segura o indirecta son re-entrant . Si sus manejadores de eventos están generando inadvertidamente otros eventos que no puede manejar de manera segura, puede decir que tiene un código no reentrante.

En C #, aquí hay un ejemplo de código que muestra una condición de carrera:

private void button1_Click(object sender, EventArgs e)
{
    if (timer1.Enabled)
        throw new InvalidOperationException("We're already ticking, you really should wait!");

    timer1.Interval = 5000;
    timer1.Start();
}

private void timer1_Tick(object sender, EventArgs e)
{
    MessageBox.Show("Okie Dokie");
    timer1.Stop();
}

Aquí hay un ejemplo simple de código que muestra un problema con la reentrada:

private void dataGridView1_CurrentCellChanged(object sender, EventArgs e)
{
    //move to the next cell if we are in the first cell
    if (dataGridView1.CurrentCell != null &&
        dataGridView1.CurrentCell.RowIndex == 0 &&
        dataGridView1.CurrentCell.ColumnIndex == 0)
    {
        //this throws an InvalidOperationException because the Microsoft DataGridView
        //does not handle Re-entrant calls to SetCurrentCellAddressCore
        dataGridView1.CurrentCell = dataGridView1[1, 0];
    }
}

Hay varias formas de resolver este tipo de problemas. Dos formas son a través de exclusión mutua (como con bloqueo ) o evitando la condición de carrera o la reentrada por completo.

Solución simple para el ejemplo # 1 utilizando la exclusión mutua:

private void button1_Click(object sender, EventArgs e)
{
    if (timer1.Enabled)
        return; //just silently ignore, maybe throw up a message box

    timer1.Interval = 5000;
    timer1.Start();
}

private void timer1_Tick(object sender, EventArgs e)
{
    MessageBox.Show("Okie Dokie");
    timer1.Stop();
}

Esquina de Nitpicker: el bloqueo no es necesario en este caso porque todo el código se está ejecutando en el subproceso de la interfaz de usuario.

Aquí hay una solución al ejemplo # 2 que evita el problema por completo:

private void button1_Click(object sender, EventArgs e)
{
    Timer newTimer = new Timer() { Interval = 5000 };
    newTimer.Tick += new EventHandler(newTimer_Tick);
    newTimer.Start();
}

void newTimer_Tick(object sender, EventArgs e)
{
    MessageBox.Show("Okie Dokie");
    ((Timer)sender).Dispose();  //probably not great to dispose in the middle of an eventhandler, but you get the idea...
}

Aquí hay una solución al ejemplo # 3 que evita el problema de la nueva entrada:

private void dataGridView1_CurrentCellChanged(object sender, EventArgs e)
{
    //move to the next cell if we are in the first cell
    if (dataGridView1.CurrentCell != null &&
        dataGridView1.CurrentCell.RowIndex == 0 &&
        dataGridView1.CurrentCell.ColumnIndex == 0)
    {
        //this does not throw an exception because 
        //the CurrentCell will be set some time later
        dataGridView1.BeginInvoke(new MethodInvoker(() =>
            {
                dataGridView1.CurrentCell = dataGridView1[1, 0];
            }));
    }
}
    
respondido por el Kevin McCormick 17.11.2011 - 16:18
12

En el diseño electrónico, el problema se conoce como contacto bounce .

La corrección del problema cuando ocurre con eventos a veces se denomina de rebote , y recibe el nombre de bits de circuitos electrónicos que hacen lo mismo. Así que supongo que podrías llamar al problema evento bounce .

    
respondido por el Blrfl 17.11.2011 - 12:33
2

No sé si hay un término general aceptado para ello. Sin embargo, lo habría nombrado como

  
  • evento inundación O
  •   
  • cadena de activación
  •   
    
respondido por el Dipan Mehta 17.11.2011 - 15:15
2

Creo que estás tocando dos categorías de errores:

  1. Suponiendo unidad en presencia de multiplicidad, y
  2. condiciones de carrera.

Se me ocurrieron esos nombres, no creo que sean estándar.

Editar: me gusta el respuesta por Kevin, que menciona la reentrada. Este es un término estándar. La falta de reingreso supone que una función solo puede ocurrir una vez en cualquier seguimiento de pila.

    
respondido por el Joh 17.11.2011 - 13:00

Lea otras preguntas en las etiquetas