DIspose添加

This commit is contained in:
hsc
2026-06-11 15:45:29 +08:00
parent 9c661200b9
commit 5cac253cb8
8 changed files with 164 additions and 17 deletions

View File

@@ -678,10 +678,6 @@ namespace ADP.ViewModels
}
}
_globalInfo.ContextDic.Remove(targetRegionName);
_globalInfo.StepRunningDic.Remove(targetRegionName);
_globalInfo.ScopeDic.Remove(targetRegionName);
var parameters = new NavigationParameters { { "Name", targetRegionName } };
_regionManager.RequestNavigate(targetRegionName, "ProtocolStartView", parameters);
_eventAggregator.GetEvent<ExpandViewEvent>().Publish("");

View File

@@ -79,20 +79,34 @@ namespace MainModule.ViewModels
public void Dispose()
{
// 1. 如果 TestStatus 为空,说明还没走到 OnNavigatedTo 赋值,直接释放 scope 即可
if (string.IsNullOrEmpty(TestStatus))
{
_scope?.Dispose();
return;
}
try
{
// 2. 显式释放硬件资源(防止端口占用/死锁)
if (_deviceManager is IDisposable disposableDevice)
{
disposableDevice.Dispose();
}
(CommandTreeVM as IDisposable)?.Dispose();
(StepsManagerVM as IDisposable)?.Dispose();
(SingleStepEditVM as IDisposable)?.Dispose();
(LogAreaVM as IDisposable)?.Dispose();
(ParametersManagerVM as IDisposable)?.Dispose();
_globalInfo.ContextDic?.Remove(TestStatus);
_globalInfo.StepRunningDic?.Remove(TestStatus);
_globalInfo.ConfigDic?.Remove(TestStatus);
_globalInfo.ScopeDic?.Remove(TestStatus);
}
catch (Exception ex)
{
Logger.LoggerHelper.ErrorWithNotify($"卸载机台 [{TestStatus}] 全局引用失败: {ex.Message}");
Logger.LoggerHelper.ErrorWithNotify($"卸载机台 [{TestStatus}] 全局引用或资源失败: {ex.Message}");
}
finally
{

View File

@@ -84,7 +84,19 @@ namespace SettingModule.ViewModels
public void Dispose()
{
_scope?.Dispose();
try
{
if (DeviceList != null)
{
DeviceList = null!;
}
SelectedDevice = null;
_scopedContext = null!;
}
catch (Exception ex)
{
Logger.LoggerHelper.ErrorWithNotify($"释放配置管理组件SettingViewModel资源失败: {ex.Message}");
}
}
#region
@@ -191,5 +203,6 @@ namespace SettingModule.ViewModels
}
}
#endregion
}
}

View File

@@ -24,7 +24,7 @@ using NLog;
namespace TestingModule.ViewModels
{
public class CommandTreeViewModel:NavigateViewModelBase
public class CommandTreeViewModel:NavigateViewModelBase,IDisposable
{
#region
private string _SearchText;
@@ -108,7 +108,25 @@ namespace TestingModule.ViewModels
ReloadCommand = new DelegateCommand(Reload);
}
public void Dispose()
{
try
{
_ScopedContext = null!;
InstructionTree?.Clear();
SubPrograms?.Clear();
TreeNodeMap?.Clear();
XmlDocumentCache?.Clear();
InstructionTree = null!;
SubPrograms = null!;
TreeNodeMap = null!;
XmlDocumentCache = null!;
}
catch (Exception ex)
{
LoggerHelper.Error($"清理指令树缓存失败: {ex.Message}");
}
}
#region
private void Reload()
{
@@ -584,6 +602,8 @@ namespace TestingModule.ViewModels
}
}
#endregion
}

View File

@@ -11,12 +11,11 @@ using UIShare.ViewModelBase;
namespace TestingModule.ViewModels
{
public class LogAreaViewModel : NavigateViewModelBase
public class LogAreaViewModel : NavigateViewModelBase, IDisposable
{
// 日志集合
private ObservableCollection<LogItem> _logs = new();
public ObservableCollection<LogItem> Logs
{
get => _logs;
@@ -27,18 +26,42 @@ namespace TestingModule.ViewModels
public LogAreaViewModel(IContainerProvider containerProvider) : base(containerProvider)
{
ClearLogCommand = new DelegateCommand(ClearLog);
// 2. 保持原有逻辑,但请确保在 Dispose 中对其进行清理
LoggerHelper.Progress = new System.Progress<(string message, string color, int depth)>(
log =>
{
// 增加防御性代码:防止进入销毁流程时异步回调引发空引用异常
if (Logs == null) return;
var brush = (Brush)new BrushConverter().ConvertFromString(log.color);
Logs.Add(new LogItem(log.message, brush, log.depth));
});
}
private void ClearLog()
{
Logs.Clear();
Logs?.Clear();
}
/// <summary>
/// 完善后的资源释放方法
/// </summary>
public void Dispose()
{
try
{
LoggerHelper.Progress = null!;
if (Logs != null)
{
Logs.Clear();
Logs = null!;
}
}
catch (Exception ex)
{
Logger.LoggerHelper.ErrorWithNotify($"释放日志组件LogAreaViewModel资源失败: {ex.Message}");
}
}
}

View File

@@ -12,7 +12,7 @@ using Prism.Events;
namespace TestingModule.ViewModels
{
public class ParametersManagerViewModel:NavigateViewModelBase
public class ParametersManagerViewModel:NavigateViewModelBase, IDisposable
{
#region
//private ObservableCollection<DeviceConfigModel> _DeviceList;
@@ -160,6 +160,24 @@ namespace TestingModule.ViewModels
#endregion
public void Dispose()
{
try
{
DeviceInfoVM?.Clear();
DeviceInfoVM = null!;
SelectedParameter = null!;
SelectedDevice = null!;
if (_ScopedContext != null)
{
_ScopedContext.SelectedParameter = null;
_ScopedContext = null!;
}
}
catch (Exception ex)
{
Logger.LoggerHelper.Error($"释放参数管理组件ParametersManagerViewModel资源失败: {ex.Message}");
}
}
}
}

View File

@@ -18,7 +18,7 @@ using UIShare.GlobalVariable;
namespace TestingModule.ViewModels
{
public class SingleStepEditViewModel:NavigateViewModelBase
public class SingleStepEditViewModel:NavigateViewModelBase,IDisposable
{
#region
private Guid _ID;
@@ -196,6 +196,26 @@ namespace TestingModule.ViewModels
SelectedStep = new StepVM(_ScopedContext.SelectedStep);
}
#endregion
public void Dispose()
{
try
{
// 1. 【核心修复】必须严格退订所有全局 Prism 事件
_eventAggregator?.GetEvent<EditSetpEvent>()?.Unsubscribe(EditSingleStep);
_eventAggregator?.GetEvent<DeletedStepEvent>()?.Unsubscribe(DisposeSelectedStep);
_eventAggregator?.GetEvent<ParamsChangedEvent>()?.Unsubscribe(ParamsChanged);
// 2. 清空当前正在编辑的步骤副本,断开前台绑定,防止 UI 视图树悬挂
SelectedStep = null!;
// 3. 断开对工位隔离上下文的强引用
_ScopedContext = null!;
}
catch (Exception ex)
{
LoggerHelper.Error($"释放单步编辑组件SingleStepEditViewModel资源失败: {ex.Message}");
}
}
}
}

View File

@@ -17,7 +17,7 @@ using Prism.Events;
namespace TestingModule.ViewModels
{
public class StepsManagerViewModel:NavigateViewModelBase
public class StepsManagerViewModel:NavigateViewModelBase, IDisposable
{
#region
private string _Title;
@@ -231,7 +231,50 @@ namespace TestingModule.ViewModels
}
}
#endregion
public void Dispose()
{
try
{
// 1. 【核心修复】必须取消订阅 CollectionChanged 事件,否则 VM 永远无法被释放
if (Program != null)
{
if (Program.StepCollection != null)
{
Program.StepCollection.CollectionChanged -= StepCollection_CollectionChanged;
}
if (Program.ErrorStepCollection != null)
{
Program.ErrorStepCollection.CollectionChanged -= StepCollection_CollectionChanged;
}
}
// 2. 【核心修复】必须显式退订 Prism 全局事件AlarmEvent
// 注意:因为订阅时使用的是匿名 Lambda最安全稳妥的退订方式是把整个事件上的当前 VM 订阅者全部注销
_eventAggregator?.GetEvent<AlarmEvent>()?.Unsubscribe(null);
// 3. 清空临时缓存集合与 UI 绑定列表,避免悬挂指针
tmpCopyList?.Clear();
tmpCopyList = null!;
SelectedItems?.Clear();
SelectedItems = null!;
// 4. 清除选中项状态引用
SelectedStep = null;
if (_ScopedContext != null)
{
_ScopedContext.SelectedStep = null;
_ScopedContext = null!; // 断开上下文引用
}
}
catch (Exception ex)
{
Logger.LoggerHelper.Error($"释放步骤管理组件StepsManagerViewModel资源失败: {ex.Message}");
}
}
}
}