Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Is there a name for a family of bugs, that are caused by assumption, that user would generate only 1 event during the execution of the handler ?

Simplest example is: animation triggered by click, which can run several copies of itself, if user rapidly clicks several times.

share|improve this question
add comment

4 Answers

up vote 9 down vote accepted

What you have described is an excellent example of a...

Race Condition

A race condition (applicable to both electronics and with programming) is when "the output and/or result of the process is unexpectedly and critically dependent on the sequence or timing of other events."

You have also described an issue with...

Reentrancy

In general, methods that may safely directly or indirectly call themselves are re-entrant. If your event handlers are inadvertently raising other events that you cannot safely handle, you can say that you have non-reentrant code.

In C#, here is an example of code that exhibits a race condition:

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

Here is a simple example of code that exhibits a problem with reentrancy:

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

There are a number of ways to solve these types of problems. Two ways are through mutual exclusion ( such as with locking) or by avoiding the race condition or re-entrancy altogether.

Simple solution to example #1 using mutual exclusion:

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

Nitpicker's corner: locking is not necessary in this case because all code is running on the UI thread.

Here's a solution to example #2 that avoids the issue altogether:

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

Here's a solution to example #3 that avoids the re-entrancy issue:

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];
            }));
    }
}
share|improve this answer
    
You had me at "reentrancy" –  Scott Whitlock Nov 17 '11 at 15:42
    
upvote for "Reentrancy" too –  Adrian Shum Nov 18 '11 at 8:45
    
Its definitely Reentrancy. Kevin, thanx for great answer! –  c69 Nov 21 '11 at 1:34
add comment

In electronic design, the problem is referred to as contact bounce.

The correction for the problem when it happens with events is sometimes referred to as de-bouncing, named after bits of electronic circuitry that do the same thing. So I suppose you could call the problem event bounce.

share|improve this answer
1  
The question wasnt about electronic design –  Tom Squires Nov 17 '11 at 11:52
9  
Nevertheless, the concept seems applicable to GUIs. After all, the term "bug" initially applied to hardware-related issues, but was transposed to software. You can criticize the author for not providing a definitive answer, but it's still an interesting remark, IMO. –  Joh Nov 17 '11 at 12:04
2  
The concept is very applicable to GUIs and anything else that generates events. In embedded systems, contact bounce is frequently corrected in software because it's easier and cheaper than adding a debounce circuit to each switch. –  Blrfl Nov 17 '11 at 13:06
add comment

I don't know if there is a general accepted term for it. However, i would have named it as

  • event flood OR
  • trigger chain
share|improve this answer
1  
I like event flood, though it makes me picture literally hundreds of excess events, not the 2 or 3 implied by the question. –  FrustratedWithFormsDesigner Nov 17 '11 at 15:19
    
+1, I've heard "event flood" on occasion before. "Trigger chain" sounds like something else, though - like one event causes another, which causes another... –  Izkata Nov 17 '11 at 16:39
add comment

I think you are touching two categories of bugs:

  1. Assuming unity in the presence of multiplicity, and
  2. race conditions.

I just came up with those names, I don't think they are standard.

Edit: I like the answer by Kevin, which mentions reentrance. This is a standard term. Lack of reentrance is assuming a function can only happen once in any stack trace.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.