Esiste un nome per il bug "Più eventi del previsto"?

7

Esiste un nome per una famiglia di bug , causato dall'assunzione, che l'utente genererebbe solo 1 evento durante l'esecuzione del gestore?

L'esempio più semplice è: l'animazione attivata dal clic, che può eseguire diverse copie di se stessa, se l'utente fa clic più volte più rapidamente.

    
posta c69 17.11.2011 - 12:21
fonte

4 risposte

9

Quello che hai descritto è un eccellente esempio di ...

Condizioni di gara

Una condizione di razza (applicabile sia all'elettronica che alla programmazione) è quando "il l'output e / o il risultato del processo dipendono in modo inaspettato e critico dalla sequenza o dai tempi di altri eventi. "

Hai anche descritto un problema con ...

Reentrancy

In generale, i metodi che possono chiamarsi direttamente o indirettamente in modo sicuro sono re-entrant . Se i tuoi gestori di eventi stanno inavvertitamente innalzando altri eventi che non puoi gestire in modo sicuro, puoi dire di avere un codice non rientranti.

In C #, ecco un esempio di codice che mostra una condizione di competizione:

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();
}

Ecco un semplice esempio di codice che presenta un problema di rientranza:

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];
    }
}

Esistono diversi modi per risolvere questi tipi di problemi. Due modi sono attraverso mutua esclusione (come con locking ) o evitando del tutto le condizioni della gara o il rientro.

Soluzione semplice per l'esempio n. 1 che utilizza l'esclusione reciproca:

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();
}

Angolo di Nitpicker: il blocco non è necessario in questo caso perché tutto il codice è in esecuzione sul thread dell'interfaccia utente.

Ecco una soluzione dell'esempio n. 2 che evita del tutto il problema:

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...
}

Ecco una soluzione dell'esempio n. 3 che evita il problema della reintroduzione:

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];
            }));
    }
}
    
risposta data 17.11.2011 - 16:18
fonte
12

Nella progettazione elettronica, il problema viene definito come rimbalzo dei contatti .

La correzione del problema quando si verifica con gli eventi viene talvolta definita de-bouncing , che prende il nome da bit di circuiti elettronici che fanno la stessa cosa. Quindi suppongo che potresti chiamare il problema rimbalzo dell'evento .

    
risposta data 17.11.2011 - 12:33
fonte
2

Non so se c'è un termine generale accettato per questo. Tuttavia, lo avrei chiamato come

  • event flood OR
  • trigger chain
    
risposta data 17.11.2011 - 15:15
fonte
2

Penso che tu stia toccando due categorie di bug:

  1. Assunzione di unità in presenza di molteplicità e
  2. condizioni di gara.

Ho appena trovato questi nomi, non penso che siano standard.

Modifica: mi piace risposta di Kevin, che menziona il rientro. Questo è un termine standard. La mancanza di rientro presuppone che una funzione possa accadere solo una volta in qualsiasi traccia dello stack.

    
risposta data 17.11.2011 - 13:00
fonte

Leggi altre domande sui tag