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 } };
|
||||
_regionManager.RequestNavigate(targetRegionName, "ProtocolStartView", parameters);
|
||||
_eventAggregator.GetEvent<ExpandViewEvent>().Publish("");
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
@@ -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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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}");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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}");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user