Игнорирование кода пока он выполняется

Здравствуйте.
Давно назрел вопрос но все никак не могу найти объективное решение.

Допустим у меня есть два объекта которые завязаны на одно событие.
В событии производится некоторая операция которая опять приводит к срабатыванию того же самого события. Существует ли какой нибудь способ в C# поставить игнор в определенном месте но чтобы событие не ожидало (Mutex, lock) а игнорировало выполнение.

Сейчас я просто создаю логический флаг

            bool BlockChanging = false;
            private void lvUserGrid_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
            {
                if (!BlockChanging)
                {
                    BlockChanging = true;
                    .. какой то код...
                    BlockChanging = false;
                }
            }

Код работает но создавать кучу флагов как то кажется неправильным.

почему кучу? ровно столько, сколько процедур с критическим кодом (которые не должны вызываться повторно (реентерабельно)), пока тело процедуры не выполнилось.
я бы только имя переменным дал исходя из имени метода, к которому они относятся
например, для lvUserGrid_ColumnWidthChanged переменная islvUserGrid_ColumnWidthChanged_Execute

это раз.
а теперь второе.
многие методы для обработки изменений можно выключать обработчик в начале и включать в конце.
например,

private void lvUserGrid_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
            {
                sender.ColumnWidthChanged -= lvUserGrid_ColumnWidthChanged; // условно так
                  .. какой то код...
                sender.ColumnWidthChanged += lvUserGrid_ColumnWidthChanged; // условно так
                }

Это вы выключите только у источника. А если код затрагивает другие компоненты, например текстовые поля, то те контролы породят свои цепочки событий.

Это понятно. Тут имя просто для примера взято.

Мне казалось МС какой то более читабельный механизм могли придумать… странно что нет.

кто сказал - что нет? :wink: я про такой не знаю, но это совершенно не говорит о том, что такого механизма нет.

кстати, а какой такой страшный код скрывается за

что он не допускает повторного вызова?
ведь как раз встроенный механизм сам отработает несколько одновременных вызовов и, в общем случае, конфликт не должен возникать.

Да ничего страшного просто там нужно все столбцы сделать по ширине такими же как последний измененный. И если не закрывать обработчик то они будут бесконечно друг друга порождать пока не вылетят в Exception.

bool BlockChanging = false;
        private void GridsColumnAlignement(object sender, DataGridViewColumnEventArgs e)
        {
            if (!BlockChanging)
            {
                BlockChanging = true;
                DataGridView target = (sender as DataGridView) == lvUserGrid ? cpecDtGrid : lvUserGrid;
                DataGridView targetother = (sender as DataGridView) != lvUserGrid ? cpecDtGrid : lvUserGrid;
                if (targetother.ColumnCount < e.Column.Index && target.ColumnCount < e.Column.Index)
                        targetother.Columns[e.Column.Index].Width = target.Columns[e.Column.Index].Width;
                BlockChanging = false;
            }
        }

А чего там может быть такого встроенного? В делфи, например, или флаг, или, на крайний случай, сброс в nil значение свойства, с последующим восстановлением естесно. А ситуации такие случаются, в OnChange например

Вместо

лучше писать

if (BlockChanging)
    return;

Проще читать, меньше вложенность. https://en.wikipedia.org/wiki/Guard_(computer_science)

Я думаю флагами проще всего.
Можно ещё попробовать асинхронный код
Служебные слова Async и Await
https://blog.stephencleary.com/2012/02/async-and-await.html

В теории ООП такое решается так над компонентом создается класс наследник в котором разделением модель и контроль. И применением шаблона обходчика.

Повторю что проще с флагом.

Думаю можно поискать примеры по ключевым словам:
BeginUpdate /EndUpdate
isValid
Invalidate
BlockChanging

Тут это вряд ли как-то поможет, тут же всё просто об UI: при изменении ширины столбца установить такую же ширину столбцу в другой таблице. И на всех висит один и тот же обработчик события.


Чтобы не было бесконечных циклов можно проверять не стоит ли уже это значение. Так часто делают в сетерах свойств, странно, что DataGridView не так (хотя тут может более сложный случай если при изменении ширины одного столбца меняются другие).

Сообщение было перенесено в новую тему: Как исправить ошибку в таблице SQL?