Home > database >  C# event handler not removed in a timely manner
C# event handler not removed in a timely manner

Time:02-15

I have a Windows Forms-based C# project with a Form having around 30-50 fields (Texts, ComboBoxes, etc.) I use a function for adding the same event hanlder function for all:

private readonly EventHandler hProjectBecameModified;
hProjectBecameModified = new EventHandler(ProjectBecameModified);

private void AddEventHandlers()
{
    RemoveEventHandlers();

    foreach (var _list in new List<TableLayoutControlCollection> {
        tableLayoutPanelGeneral.Controls,
        tableLayoutPanelReverse.Controls,
        tableLayoutPanelBuild.Controls,
        tableLayoutPanelLocalization.Controls,
        })
    {
        foreach (var control in _list)
        {
            if (control.GetType() == typeof(ComboBox))
                (control as ComboBox).SelectedIndexChanged  = hProjectBecameModified;
            else if (control.GetType() == typeof(CheckBox))
                (control as CheckBox).CheckedChanged  = hProjectBecameModified;
            else if (control.GetType() == typeof(TextBox))
                (control as TextBox).TextChanged  = hProjectBecameModified;
        }
    }
}

private void ProjectBecameModified(object sender, EventArgs e)
{
    m_isSelectedProjectToBeSaved = true;
    //Etc, user modified the stuff and it is to be saved
}

And there is a RemoveEventHandlers() function that is the same having -=s instead of =s. Note that I checked with conditional breakpoints that the function works for the actual control, so handler should be removed.

When I set stuff programically, I do it like:

RemoveEventHandlers();

//setting stuff, like
//textBoxManufacturer.Text = m_selectedProject.Manufacturer;

AddEventHandlers();

problem is that for a certain combobox, this isn't work:

RemoveEventHandlers();
comboBoxConfiguration.SelectedIndex = something;

will fire the event handling function. (Note that it has another event handler, with its own RemoveEventHandlers() and AddEventHandlers() )

However, if I write:

comboBoxConfiguration.SelectedIndexChanged -= hProjectBecameModified;
comboBoxConfiguration.SelectedIndex = something;
RemoveEventHandlers();

will work. (But if I add more RemoveEventHandlers() calls will not work).

While acutal code now works, I have concerns regarding its actual work, and why it does so.

  1. Is it a bad design?
  2. Is it somehow a racing condition, ie. the RemoveEventHandlers() might be running on a different thread and not removing event handler in time? (Would be strange).
  3. Is it possible to add the same event handler multiple times so that it causes the problem? (Unlikely).
  4. (Is the provided info enough?)

PS Note that after the first comments I added a RemoveEventHandlers() call to the first line of the AddEventHandlers() function.

CodePudding user response:

I would suggest a simpler option.

Try this:

private bool _suspended = false;

void Suspend()
{
    _suspended = true;
}

void Resume()
{
    _suspended = false;
}

private void ProjectBecameModified(object sender, EventArgs e)
{
    if (!_suspended)
    {
        m_isSelectedProjectToBeSaved = true;
        //Etc, user modified the stuff and it is to be saved
    }
}

You don't need to remove the event handlers at all this way.

  • Related