fix(legacy): complete hosted module cleanup
This commit is contained in:
@@ -157,7 +157,6 @@ namespace Lskj.PubModuleDetail
|
||||
string guid = this.Tag + "";
|
||||
if (string.IsNullOrWhiteSpace(guid))
|
||||
{
|
||||
this.mControl.ReleaseResourcesForDispose();
|
||||
return;
|
||||
}
|
||||
DllModule m = Manager.ModuleForms[guid];
|
||||
@@ -180,7 +179,6 @@ namespace Lskj.PubModuleDetail
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FormClosing fires before the control tree is disposed. Release the
|
||||
// DevExpress grids and their native resources as soon as the close is
|
||||
// confirmed; waiting for FrmMain.Dispose leaves GDI handles alive
|
||||
@@ -232,91 +230,20 @@ namespace Lskj.PubModuleDetail
|
||||
this.FormClosing -= OnClose;
|
||||
this.Disposed -= OnFrmMainDisposed;
|
||||
|
||||
// StaticControl performs the module-wide cache cleanup after the
|
||||
// shell has confirmed the close. Remove only this form's cache key
|
||||
// here; clearing the whole shared dictionary from a Disposed event
|
||||
// could affect another tab that still uses the same model cache.
|
||||
Dictionary<object, Hashtable> dataCaches =
|
||||
Model != null ? Model.DataCaches : null;
|
||||
HashSet<Task> completedTasks;
|
||||
if (dataCaches == null ||
|
||||
!TryDetachCompletedCacheTasks(dataCaches, out completedTasks))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DisposeCompletedCacheTasks(completedTasks);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放模块预加载缓存中已完成任务的等待句柄。
|
||||
/// Task.Result 在等待时可能创建底层等待对象,仅清空字典
|
||||
/// 不会立即释放这些句柄。
|
||||
/// </summary>
|
||||
private static void DisposeCompletedCacheTasks(IEnumerable<Task> tasks)
|
||||
{
|
||||
foreach (Task task in tasks)
|
||||
{
|
||||
try
|
||||
{
|
||||
task.Dispose();
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 仅当并行初始化全部完成时,才在同一同步区间摘除缓存任务。
|
||||
/// AddTask 使用同一个字典实例加锁,避免检查后又插入新任务。
|
||||
/// </summary>
|
||||
private static bool TryDetachCompletedCacheTasks(
|
||||
Dictionary<object, Hashtable> dataCaches,
|
||||
out HashSet<Task> completedTasks)
|
||||
{
|
||||
completedTasks = new HashSet<Task>();
|
||||
try
|
||||
{
|
||||
lock (dataCaches)
|
||||
{
|
||||
foreach (Hashtable cacheValues in dataCaches.Values)
|
||||
{
|
||||
if (cacheValues == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (object value in cacheValues.Values)
|
||||
{
|
||||
Task task = value as Task;
|
||||
if (task == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (!task.IsCompleted)
|
||||
{
|
||||
completedTasks.Clear();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
completedTasks.Add(task);
|
||||
}
|
||||
}
|
||||
|
||||
dataCaches.Clear();
|
||||
}
|
||||
|
||||
return true;
|
||||
if (dataCaches != null)
|
||||
dataCaches.RemoveCache(this);
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
catch (Exception exception)
|
||||
{
|
||||
completedTasks.Clear();
|
||||
return false;
|
||||
Debug.WriteLine("移除窗体动态缓存引用失败:" + exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user