From a41e13c9fec5cc59ea53b621439e20f1b11193f4 Mon Sep 17 00:00:00 2001 From: John T Maxwell III Date: Fri, 13 Dec 2024 13:29:07 -0800 Subject: [PATCH] Fix LT-22011: Adding slots lead to crash (#239) Co-authored-by: Jake Oliver --- .../Controls/DetailControls/DataTree.cs | 16 ++++++++-- .../MSAReferenceComboBoxSlice.cs | 29 ------------------- .../LexTextControls/MSAPopupTreeManager.cs | 11 ------- 3 files changed, 14 insertions(+), 42 deletions(-) diff --git a/Src/Common/Controls/DetailControls/DataTree.cs b/Src/Common/Controls/DetailControls/DataTree.cs index f05bd108c1..9303b46973 100644 --- a/Src/Common/Controls/DetailControls/DataTree.cs +++ b/Src/Common/Controls/DetailControls/DataTree.cs @@ -553,8 +553,11 @@ public void PropChanged(int hvo, int tag, int ivMin, int cvIns, int cvDel) // return; if (m_monitoredProps.Contains(Tuple.Create(hvo, tag))) { - RefreshList(false); - OnFocusFirstPossibleSlice(null); + // If we call RefreshList now, it causes a crash in the invoker + // because some slice data structures that are being used by the invoker + // get disposed by RefreshList (LT-21980, LT-22011). So we postpone calling + // RefreshList until the work is done. + this.BeginInvoke(new Action(PostponedRefreshList)); } // Note, in LinguaLinks import we don't have an action handler when we hit this. else if (m_cache.DomainDataByFlid.GetActionHandler() != null && m_cache.DomainDataByFlid.GetActionHandler().IsUndoOrRedoInProgress) @@ -581,6 +584,15 @@ public void PropChanged(int hvo, int tag, int ivMin, int cvIns, int cvDel) } } + private void PostponedRefreshList() + { + if (!IsDisposed) + { + RefreshList(false); + OnFocusFirstPossibleSlice(null); + } + } + /// public Mediator Mediator { diff --git a/Src/Common/Controls/DetailControls/MSAReferenceComboBoxSlice.cs b/Src/Common/Controls/DetailControls/MSAReferenceComboBoxSlice.cs index eefb2a0785..4c64cfc413 100644 --- a/Src/Common/Controls/DetailControls/MSAReferenceComboBoxSlice.cs +++ b/Src/Common/Controls/DetailControls/MSAReferenceComboBoxSlice.cs @@ -99,8 +99,6 @@ public override Mediator Mediator m_MSAPopupTreeManager = new MSAPopupTreeManager(m_tree, m_cache, list, m_tree.WritingSystemCode, true, m_mediator, m_propertyTable, m_propertyTable.GetValue
("window")); - m_MSAPopupTreeManager.BeforeChange += m_MSAPopupTreeManager_BeforeChange; - m_MSAPopupTreeManager.AfterChange += m_MSAPopupTreeManager_AfterChange; m_MSAPopupTreeManager.AfterSelect += m_MSAPopupTreeManager_AfterSelect; m_MSAPopupTreeManager.Sense = m_obj as ILexSense; m_MSAPopupTreeManager.PersistenceProvider = m_persistProvider; @@ -225,33 +223,6 @@ protected override void UpdateDisplayFromDatabase() // What do we need to do here, if anything? } - public void m_MSAPopupTreeManager_BeforeChange(object sender, TreeViewEventArgs e) - { - if (!ContainingDataTree.DoNotRefresh) - { - // Postpone refreshing the screen until m_MSAPopupTreeManager_AfterChange (LT-21980). - ContainingDataTree.DoNotRefresh = true; - m_forceRefresh = true; - } - } - - public void m_MSAPopupTreeManager_AfterChange(object sender, TreeViewEventArgs e) - { - if (m_forceRefresh) - { - m_forceRefresh = false; - // We can't call RefreshDataTree directly, - // since that will cause Windows to crash accessing a disposed object. - // So, we queue it on the UI thread instead. - this.BeginInvoke(new Action(RefreshDataTree)); - } - } - - public void RefreshDataTree() - { - ContainingDataTree.DoNotRefresh = false; - } - private void m_MSAPopupTreeManager_AfterSelect(object sender, TreeViewEventArgs e) { // unless we get a mouse click or simulated mouse click (e.g. by ENTER or TAB), diff --git a/Src/LexText/LexTextControls/MSAPopupTreeManager.cs b/Src/LexText/LexTextControls/MSAPopupTreeManager.cs index 4ed27add30..b294d55807 100644 --- a/Src/LexText/LexTextControls/MSAPopupTreeManager.cs +++ b/Src/LexText/LexTextControls/MSAPopupTreeManager.cs @@ -44,9 +44,6 @@ public class MSAPopupTreeManager : PopupTreeManager #region Events - public event TreeViewEventHandler BeforeChange; - public event TreeViewEventHandler AfterChange; - #endregion Events /// @@ -422,19 +419,11 @@ private bool EditExistingMsa() m_sense.MorphoSyntaxAnalysisRA.Hvo, true, m_sEditGramFunc); if (dlg.ShowDialog(ParentForm) == DialogResult.OK) { - if (BeforeChange != null) - { - BeforeChange(this, null); - } Cache.DomainDataByFlid.BeginUndoTask(String.Format(LexTextControls.ksUndoSetX, FieldName), String.Format(LexTextControls.ksRedoSetX, FieldName)); m_sense.SandboxMSA = dlg.SandboxMSA; Cache.DomainDataByFlid.EndUndoTask(); LoadPopupTree(m_sense.MorphoSyntaxAnalysisRA.Hvo); - if (AfterChange != null) - { - AfterChange(this, null); - } return true; } }