fix: 收敛旧控件资源与后台线程生命周期

This commit is contained in:
2026-08-11 14:12:18 +08:00
parent f1ce6ff658
commit a9c986f9d5
20 changed files with 1145 additions and 380 deletions
+109 -4
View File
@@ -63,6 +63,9 @@ namespace Lskj.Main.Model
private static CancellationTokenSource _sessionMonitorCancellation;
private static readonly List<Thread> SessionMonitorThreads =
new List<Thread>();
private static readonly object OpeningModuleSync = new object();
private static readonly HashSet<string> OpeningModuleKeys =
new HashSet<string>(StringComparer.OrdinalIgnoreCase);
/// <summary>
/// 默认下载地址
/// </summary>
@@ -285,6 +288,8 @@ namespace Lskj.Main.Model
/// Params">The URL parameters.</param>
public static void OpenModule(string menuId, string menuName, string dllName, string modelFlag, string urlParams)
{
string openingModuleKey = null;
bool ownsOpeningGate = false;
try
{
// 验证参数
@@ -293,6 +298,14 @@ namespace Lskj.Main.Model
MessageUtil.Show(ResourceKeys.NotFoundMenu);
return;
}
openingModuleKey = BuildOpeningModuleKey(menuId, dllName, modelFlag);
ownsOpeningGate = TryBeginOpenModule(openingModuleKey);
if (!ownsOpeningGate)
{
// 列数据源初始化期间可能会处理 WinForms 消息。
// 快速重复点击必须在页签注册前就被拦截,否则会构建多份重型控件树。
return;
}
// 验证权限
int purview = MainImpl.GetUserPurviewsByMenuId(menuId);
if (purview == 0)
@@ -416,8 +429,52 @@ namespace Lskj.Main.Model
string Message = ErrorMessage.PromptErrorMessage(ex);
MessageUtil.Show(Message, ex.Message);
}
finally
{
if (ownsOpeningGate)
{
EndOpenModule(openingModuleKey);
}
}
}
private static string BuildOpeningModuleKey(
string menuId,
string dllName,
string modelFlag)
{
return string.Join(
"|",
new[]
{
(menuId ?? string.Empty).Trim(),
(dllName ?? string.Empty).Trim(),
(modelFlag ?? string.Empty).Trim()
});
}
private static bool TryBeginOpenModule(string openingModuleKey)
{
lock (OpeningModuleSync)
{
if (OpeningModuleKeys.Contains(openingModuleKey))
{
return false;
}
OpeningModuleKeys.Add(openingModuleKey);
return true;
}
}
private static void EndOpenModule(string openingModuleKey)
{
lock (OpeningModuleSync)
{
OpeningModuleKeys.Remove(openingModuleKey);
}
}
/// <summary>
/// <para>说明:添加模块到tab中</para>
/// <para>创建人:龚宇超</para>
@@ -432,6 +489,10 @@ namespace Lskj.Main.Model
/// <param name="args">The arguments.</param>
public static void AddModuleToTab(DllModule module, string[] args)
{
string guid = null;
XtraTabPage tp = null;
Form form = null;
bool trackDogVerifiedModule = false;
try
{
bool isQuickLoad = (args[5] + "").Equals(SystemInfo.Instance.QuickMenuId);
@@ -441,8 +502,6 @@ namespace Lskj.Main.Model
// //QuickMenuForm.BringToFront();
// return;
//}
string guid = Guid.NewGuid().ToString();
XtraTabPage tp = new XtraTabPage();
if (SystemInfo.Instance.IsDogVerify)
{
if (!CheckPrivateTable())
@@ -497,7 +556,7 @@ namespace Lskj.Main.Model
}
else
{
StaticControl.DogVerifyModuleForms.Add(tp);
trackDogVerifiedModule = true;
}
}
else
@@ -532,12 +591,19 @@ namespace Lskj.Main.Model
return;
}
guid = Guid.NewGuid().ToString();
tp = new XtraTabPage();
if (trackDogVerifiedModule)
{
StaticControl.DogVerifyModuleForms.Add(tp);
}
ERPInfo.Instance.selectFormModleId = module.Id;
IForm iform = FormHelper.LoadDllForm(module.DllName, args);
// 菜单打开的模块默认最大化,界面FormState设置为Normal模式,否则会出现界面不是全屏,会显示默认阴影界面
//iform.SubForm.WindowState = _frmMain.WindowState;
iform.SubForm.WindowState = FormWindowState.Normal; ;
Form form = iform.SubForm; // 表示组成应用程序的用户界面的窗口或对话框。
form = iform.SubForm; // 表示组成应用程序的用户界面的窗口或对话框。
form.Tag = guid;
// 这个必须有不然会提示:"不能向tabControl中添加顶级控件"
form.TopLevel = isQuickLoad;
@@ -599,6 +665,7 @@ namespace Lskj.Main.Model
}
catch (Exception ex)
{
CleanupFailedModuleOpen(guid, tp, form);
string Message = ErrorMessage.PromptErrorMessage(ex);
MessageUtil.Show(ex.InnerException != null ? ex.InnerException.Message : ex.Message);
LogHelper.Instance.WriteError(ex);
@@ -606,6 +673,44 @@ namespace Lskj.Main.Model
}
}
private static void CleanupFailedModuleOpen(
string guid,
XtraTabPage tabPage,
Form form)
{
try
{
if (!string.IsNullOrWhiteSpace(guid))
{
ModuleForms.Remove(guid);
}
if (tabPage != null)
{
StaticControl.DogVerifyModuleForms.Remove(tabPage);
if (TabMain != null && TabMain.TabPages.Contains(tabPage))
{
TabMain.TabPages.Remove(tabPage);
}
}
if (form != null && !form.IsDisposed)
{
form.Close();
form.Dispose();
}
if (tabPage != null && !tabPage.IsDisposed)
{
tabPage.Dispose();
}
}
catch (Exception cleanupException)
{
LogHelper.Instance.WriteError(cleanupException);
}
}
/// <summary>
/// 快速菜单关闭时,清除记录
/// </summary>