fix(legacy): release hosted module resources safely
This commit is contained in:
@@ -634,6 +634,7 @@ namespace Lskj.Control
|
||||
// 模块级清理只解除事件和菜单引用。GridControl/GridView 的生命周期
|
||||
// 由真正的 WinForms 父容器负责,并在 Dispose(bool) 中统一结束。
|
||||
DetachGridViewEventHandlers();
|
||||
DisposeOwnedLookupFormsForDispose();
|
||||
if (gridViewRightMenu != null)
|
||||
{
|
||||
gridViewRightMenu.ReleaseResourcesForDispose();
|
||||
@@ -683,6 +684,70 @@ namespace Lskj.Control
|
||||
LabPicUrlPreview.Detach(gridView);
|
||||
}
|
||||
|
||||
private void DisposeOwnedLookupFormsForDispose()
|
||||
{
|
||||
HashSet<Form> forms = new HashSet<Form>();
|
||||
foreach (FrmModelLookUp2 modelLookUp in
|
||||
selectReturnModelLookUpCache.Values.Distinct())
|
||||
{
|
||||
if (modelLookUp != null)
|
||||
{
|
||||
forms.Add(modelLookUp);
|
||||
}
|
||||
}
|
||||
|
||||
selectReturnModelLookUpCache.Clear();
|
||||
selectReturnDisplaySourceCache.Clear();
|
||||
|
||||
RepositoryItem[] repositoryItems = null;
|
||||
try
|
||||
{
|
||||
if (gridControl != null)
|
||||
{
|
||||
repositoryItems = gridControl.RepositoryItems
|
||||
.Cast<RepositoryItem>()
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// The inner control may already be disposing its repository collection.
|
||||
}
|
||||
|
||||
if (repositoryItems != null)
|
||||
{
|
||||
foreach (RepositoryItemButtonEdit buttonEditor in
|
||||
repositoryItems.OfType<RepositoryItemButtonEdit>())
|
||||
{
|
||||
foreach (EditorButton button in buttonEditor.Buttons)
|
||||
{
|
||||
Form form = button.Tag as Form;
|
||||
if (form == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
button.Tag = null;
|
||||
forms.Add(form);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Form form in forms)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!form.IsDisposed)
|
||||
{
|
||||
form.Dispose();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// A helper form must not prevent its owning grid from closing.
|
||||
}
|
||||
}
|
||||
}
|
||||
private void DisposeGridResources()
|
||||
{
|
||||
if (_gridResourcesDisposed)
|
||||
@@ -723,6 +788,7 @@ namespace Lskj.Control
|
||||
mControlList.Clear();
|
||||
ColumnList.Clear();
|
||||
AutoPadDataReleColList.Clear();
|
||||
DisposeOwnedLookupFormsForDispose();
|
||||
FrozenColumns.Clear();
|
||||
ImageList.Clear();
|
||||
RepeatedVerificationNames.Clear();
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
ReleaseLookupFormForDispose();
|
||||
}
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
|
||||
@@ -315,6 +315,7 @@ namespace Lskj.Control
|
||||
/// <param name="dataSource">数据源</param>
|
||||
public void InitialFrame()
|
||||
{
|
||||
ReleaseLookupFormForDispose();
|
||||
_lookUpForm = new FrmModelLookUp2(UnionModuleCodel, IsRadio);
|
||||
_lookUpForm.ConfigureColumnMode = ConfigureColumnMode;
|
||||
_lookUpForm.ValueField = ValueField;
|
||||
@@ -332,6 +333,25 @@ namespace Lskj.Control
|
||||
/// <para>修改备注:</para>
|
||||
/// <para>版本:1.0</para>
|
||||
/// </summary>
|
||||
internal void ReleaseLookupFormForDispose()
|
||||
{
|
||||
FrmModelLookUp2 lookUpForm = _lookUpForm;
|
||||
_lookUpForm = null;
|
||||
if (lookUpForm == null || lookUpForm.IsDisposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
lookUpForm.Dispose();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// A helper form must not prevent its owner from closing.
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearSelectForm()
|
||||
{
|
||||
// _lookUpForm.ClearSelect();
|
||||
|
||||
@@ -126,6 +126,7 @@ namespace Lskj.Control.Model
|
||||
// 控件,不调用 Control.Dispose,也不扫描全局控件集合,因而
|
||||
// 不会影响仍然打开的模块或共享的 GridView 生命周期。
|
||||
ReleaseGridControlRuntimeReferences(moduleControls);
|
||||
ReleaseLookupControlRuntimeReferences(moduleControls);
|
||||
|
||||
foreach (GridView gridView in gridViews)
|
||||
{
|
||||
@@ -204,6 +205,33 @@ namespace Lskj.Control.Model
|
||||
}
|
||||
}
|
||||
|
||||
private static void ReleaseLookupControlRuntimeReferences(
|
||||
IEnumerable<WinFormsControl> moduleControls)
|
||||
{
|
||||
if (moduleControls == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (Lskj.Control.LabelMultiAutoTextEdit4 lookupControl in
|
||||
moduleControls.OfType<Lskj.Control.LabelMultiAutoTextEdit4>())
|
||||
{
|
||||
if (lookupControl == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
lookupControl.ReleaseLookupFormForDispose();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
TraceCleanupFailure("release lookup helper form", exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<WinFormsControl> CollectModuleControls(
|
||||
WinFormsControl moduleRoot,
|
||||
XtraTabPage modulePage)
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
DisposeDragResources();
|
||||
}
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
|
||||
@@ -174,6 +174,10 @@ namespace Lskj.Control.MultiModelLookUp
|
||||
public bool ReturnCollection;
|
||||
|
||||
#endregion
|
||||
private GridDragGrid _dragGrid;
|
||||
private GridDragGrid _backDragGrid;
|
||||
private bool _dragResourcesDisposed;
|
||||
|
||||
public FrmModelLookUp2(string ModuleCodel)
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -184,8 +188,8 @@ namespace Lskj.Control.MultiModelLookUp
|
||||
this.gcMain.GridControl.ContextMenuStrip = contextMenuStrip1;
|
||||
this.gcMain.GridView.DoubleClick += new EventHandler(OnRowCellClick);
|
||||
this.gcDetail.GridView.DoubleClick += new EventHandler(OnDoubleClick);
|
||||
GridDragGrid dragGrid = new GridDragGrid(this.gcMain.GridView, this.gcDetail.GridView);
|
||||
GridDragGrid backdragGrid = new GridDragGrid(this.gcDetail.GridView, this.gcMain.GridView);
|
||||
_dragGrid = new GridDragGrid(this.gcMain.GridView, this.gcDetail.GridView);
|
||||
_backDragGrid = new GridDragGrid(this.gcDetail.GridView, this.gcMain.GridView);
|
||||
//设置关联模块
|
||||
bool result = SetAssociatedModules();
|
||||
this.pl_top.Height = 0;
|
||||
@@ -210,8 +214,8 @@ namespace Lskj.Control.MultiModelLookUp
|
||||
this.gcMain.GridView.OptionsBehavior.EditorShowMode = DevExpress.Utils.EditorShowMode.MouseDown;
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.OnFormClosing);
|
||||
this.gcMain.GridControl.ContextMenuStrip = contextMenuStrip1;
|
||||
GridDragGrid dragGrid = new GridDragGrid(this.gcMain.GridView, this.gcDetail.GridView);
|
||||
GridDragGrid backdragGrid = new GridDragGrid(this.gcDetail.GridView, this.gcMain.GridView);
|
||||
_dragGrid = new GridDragGrid(this.gcMain.GridView, this.gcDetail.GridView);
|
||||
_backDragGrid = new GridDragGrid(this.gcDetail.GridView, this.gcMain.GridView);
|
||||
//设置关联模块
|
||||
bool result = SetAssociatedModules();
|
||||
|
||||
@@ -1108,13 +1112,50 @@ namespace Lskj.Control.MultiModelLookUp
|
||||
/// <para>修改日期:</para>
|
||||
/// <para>修改备注:</para>
|
||||
/// <para>版本:1.0</para>
|
||||
private void DisposeDragResources()
|
||||
{
|
||||
if (_dragResourcesDisposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_dragResourcesDisposed = true;
|
||||
GridDragGrid dragGrid = _dragGrid;
|
||||
_dragGrid = null;
|
||||
if (dragGrid != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
dragGrid.Dispose();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Continue releasing the reverse registration.
|
||||
}
|
||||
}
|
||||
|
||||
GridDragGrid backDragGrid = _backDragGrid;
|
||||
_backDragGrid = null;
|
||||
if (backDragGrid != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
backDragGrid.Dispose();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Drag cleanup must not block form disposal.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnFrmModelLookUp_Disposed(object sender, EventArgs e)
|
||||
{
|
||||
DisposeDragResources();
|
||||
if (this.DataSource != null)
|
||||
{
|
||||
this.DataSource = null;
|
||||
}
|
||||
GC.Collect();
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
Reference in New Issue
Block a user