DIspose添加
This commit is contained in:
@@ -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 } };
|
var parameters = new NavigationParameters { { "Name", targetRegionName } };
|
||||||
_regionManager.RequestNavigate(targetRegionName, "ProtocolStartView", parameters);
|
_regionManager.RequestNavigate(targetRegionName, "ProtocolStartView", parameters);
|
||||||
_eventAggregator.GetEvent<ExpandViewEvent>().Publish("");
|
_eventAggregator.GetEvent<ExpandViewEvent>().Publish("");
|
||||||
|
|||||||
@@ -79,20 +79,34 @@ namespace MainModule.ViewModels
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
// 1. 如果 TestStatus 为空,说明还没走到 OnNavigatedTo 赋值,直接释放 scope 即可
|
||||||
if (string.IsNullOrEmpty(TestStatus))
|
if (string.IsNullOrEmpty(TestStatus))
|
||||||
{
|
{
|
||||||
_scope?.Dispose();
|
_scope?.Dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
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.ContextDic?.Remove(TestStatus);
|
||||||
_globalInfo.StepRunningDic?.Remove(TestStatus);
|
_globalInfo.StepRunningDic?.Remove(TestStatus);
|
||||||
_globalInfo.ConfigDic?.Remove(TestStatus);
|
_globalInfo.ConfigDic?.Remove(TestStatus);
|
||||||
|
_globalInfo.ScopeDic?.Remove(TestStatus);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.LoggerHelper.ErrorWithNotify($"卸载机台 [{TestStatus}] 全局引用失败: {ex.Message}");
|
Logger.LoggerHelper.ErrorWithNotify($"卸载机台 [{TestStatus}] 全局引用或资源失败: {ex.Message}");
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -84,7 +84,19 @@ namespace SettingModule.ViewModels
|
|||||||
|
|
||||||
public void Dispose()
|
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 命令
|
#region 命令
|
||||||
@@ -191,5 +203,6 @@ namespace SettingModule.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,7 @@ using NLog;
|
|||||||
|
|
||||||
namespace TestingModule.ViewModels
|
namespace TestingModule.ViewModels
|
||||||
{
|
{
|
||||||
public class CommandTreeViewModel:NavigateViewModelBase
|
public class CommandTreeViewModel:NavigateViewModelBase,IDisposable
|
||||||
{
|
{
|
||||||
#region 属性
|
#region 属性
|
||||||
private string _SearchText;
|
private string _SearchText;
|
||||||
@@ -108,7 +108,25 @@ namespace TestingModule.ViewModels
|
|||||||
ReloadCommand = new DelegateCommand(Reload);
|
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 委托命令
|
#region 委托命令
|
||||||
private void Reload()
|
private void Reload()
|
||||||
{
|
{
|
||||||
@@ -584,6 +602,8 @@ namespace TestingModule.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,12 +11,11 @@ using UIShare.ViewModelBase;
|
|||||||
|
|
||||||
namespace TestingModule.ViewModels
|
namespace TestingModule.ViewModels
|
||||||
{
|
{
|
||||||
public class LogAreaViewModel : NavigateViewModelBase
|
public class LogAreaViewModel : NavigateViewModelBase, IDisposable
|
||||||
{
|
{
|
||||||
// 日志集合
|
// 日志集合
|
||||||
private ObservableCollection<LogItem> _logs = new();
|
private ObservableCollection<LogItem> _logs = new();
|
||||||
|
|
||||||
|
|
||||||
public ObservableCollection<LogItem> Logs
|
public ObservableCollection<LogItem> Logs
|
||||||
{
|
{
|
||||||
get => _logs;
|
get => _logs;
|
||||||
@@ -27,18 +26,42 @@ namespace TestingModule.ViewModels
|
|||||||
public LogAreaViewModel(IContainerProvider containerProvider) : base(containerProvider)
|
public LogAreaViewModel(IContainerProvider containerProvider) : base(containerProvider)
|
||||||
{
|
{
|
||||||
ClearLogCommand = new DelegateCommand(ClearLog);
|
ClearLogCommand = new DelegateCommand(ClearLog);
|
||||||
|
|
||||||
|
// 2. 保持原有逻辑,但请确保在 Dispose 中对其进行清理
|
||||||
LoggerHelper.Progress = new System.Progress<(string message, string color, int depth)>(
|
LoggerHelper.Progress = new System.Progress<(string message, string color, int depth)>(
|
||||||
log =>
|
log =>
|
||||||
{
|
{
|
||||||
|
// 增加防御性代码:防止进入销毁流程时异步回调引发空引用异常
|
||||||
|
if (Logs == null) return;
|
||||||
|
|
||||||
var brush = (Brush)new BrushConverter().ConvertFromString(log.color);
|
var brush = (Brush)new BrushConverter().ConvertFromString(log.color);
|
||||||
Logs.Add(new LogItem(log.message, brush, log.depth));
|
Logs.Add(new LogItem(log.message, brush, log.depth));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void ClearLog()
|
private void ClearLog()
|
||||||
|
{
|
||||||
|
Logs?.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 完善后的资源释放方法
|
||||||
|
/// </summary>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
LoggerHelper.Progress = null!;
|
||||||
|
if (Logs != null)
|
||||||
{
|
{
|
||||||
Logs.Clear();
|
Logs.Clear();
|
||||||
|
Logs = null!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.LoggerHelper.ErrorWithNotify($"释放日志组件(LogAreaViewModel)资源失败: {ex.Message}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ using Prism.Events;
|
|||||||
|
|
||||||
namespace TestingModule.ViewModels
|
namespace TestingModule.ViewModels
|
||||||
{
|
{
|
||||||
public class ParametersManagerViewModel:NavigateViewModelBase
|
public class ParametersManagerViewModel:NavigateViewModelBase, IDisposable
|
||||||
{
|
{
|
||||||
#region 属性
|
#region 属性
|
||||||
//private ObservableCollection<DeviceConfigModel> _DeviceList;
|
//private ObservableCollection<DeviceConfigModel> _DeviceList;
|
||||||
@@ -160,6 +160,24 @@ namespace TestingModule.ViewModels
|
|||||||
|
|
||||||
|
|
||||||
#endregion
|
#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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ using UIShare.GlobalVariable;
|
|||||||
|
|
||||||
namespace TestingModule.ViewModels
|
namespace TestingModule.ViewModels
|
||||||
{
|
{
|
||||||
public class SingleStepEditViewModel:NavigateViewModelBase
|
public class SingleStepEditViewModel:NavigateViewModelBase,IDisposable
|
||||||
{
|
{
|
||||||
#region 属性
|
#region 属性
|
||||||
private Guid _ID;
|
private Guid _ID;
|
||||||
@@ -196,6 +196,26 @@ namespace TestingModule.ViewModels
|
|||||||
SelectedStep = new StepVM(_ScopedContext.SelectedStep);
|
SelectedStep = new StepVM(_ScopedContext.SelectedStep);
|
||||||
}
|
}
|
||||||
#endregion
|
#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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ using Prism.Events;
|
|||||||
|
|
||||||
namespace TestingModule.ViewModels
|
namespace TestingModule.ViewModels
|
||||||
{
|
{
|
||||||
public class StepsManagerViewModel:NavigateViewModelBase
|
public class StepsManagerViewModel:NavigateViewModelBase, IDisposable
|
||||||
{
|
{
|
||||||
#region 属性
|
#region 属性
|
||||||
private string _Title;
|
private string _Title;
|
||||||
@@ -231,7 +231,50 @@ namespace TestingModule.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user