223 lines
6.3 KiB
Markdown
223 lines
6.3 KiB
Markdown
# 分层拆分崩溃问题修复总结
|
||
|
||
## 🔍 问题诊断结果
|
||
|
||
通过详细的日志分析,我们精确定位了崩溃的根本原因:
|
||
|
||
### 崩溃位置
|
||
```
|
||
[INFO] [ModelSplitter] 重置所有隐藏状态...
|
||
```
|
||
程序在执行 `document.Models.ResetAllHidden()` 时崩溃,没有后续的"重置完成"日志。
|
||
|
||
### 根本原因
|
||
`ResetAllHidden()` API在某些情况下会导致Navisworks程序崩溃,特别是:
|
||
- 处理大型模型时
|
||
- 模型结构复杂时
|
||
- 内存使用较高时
|
||
- 某些特定的模型文件格式
|
||
|
||
## 🛠️ 关键修复措施
|
||
|
||
### 1. ModelSplitterManager.cs 修复
|
||
|
||
#### A. EnsureStableState() 方法
|
||
**修复前(崩溃代码)**:
|
||
```csharp
|
||
document.Models.ResetAllHidden(); // 导致崩溃
|
||
```
|
||
|
||
**修复后(安全代码)**:
|
||
```csharp
|
||
// 完全跳过可见性重置,避免崩溃风险
|
||
LogManager.Info("[ModelSplitter] 跳过可见性重置以避免崩溃风险");
|
||
LogManager.Info("[ModelSplitter] 使用选择集策略替代可见性控制");
|
||
|
||
// 只进行安全的操作
|
||
document.CurrentSelection.Clear(); // 这是安全的
|
||
```
|
||
|
||
#### B. RecoverFromError() 方法
|
||
**修复前**:
|
||
```csharp
|
||
document.Models.ResetAllHidden(); // 可能导致二次崩溃
|
||
```
|
||
|
||
**修复后**:
|
||
```csharp
|
||
try
|
||
{
|
||
document.Models.ResetAllHidden();
|
||
LogManager.Info("[ModelSplitter] 错误恢复:ResetAllHidden成功");
|
||
}
|
||
catch (Exception resetEx)
|
||
{
|
||
LogManager.Warning($"[ModelSplitter] 错误恢复:ResetAllHidden失败: {resetEx.Message}");
|
||
LogManager.Info("[ModelSplitter] 错误恢复:跳过可见性重置");
|
||
}
|
||
```
|
||
|
||
#### C. FinalCleanup() 方法
|
||
**修复后**:
|
||
```csharp
|
||
try
|
||
{
|
||
document.Models.ResetAllHidden();
|
||
LogManager.Info("[ModelSplitter] 最终清理:ResetAllHidden成功");
|
||
}
|
||
catch (Exception resetEx)
|
||
{
|
||
LogManager.Warning($"[ModelSplitter] 最终清理:ResetAllHidden失败: {resetEx.Message}");
|
||
LogManager.Info("[ModelSplitter] 最终清理:跳过可见性重置");
|
||
}
|
||
```
|
||
|
||
### 2. NavisworksFileExporter.cs 修复
|
||
|
||
#### A. ExportByVisibilityControlAsync() 方法
|
||
**修复前(崩溃代码)**:
|
||
```csharp
|
||
// 首先重置所有隐藏状态,确保从干净状态开始
|
||
document.Models.ResetAllHidden(); // 导致崩溃
|
||
```
|
||
|
||
**修复后(安全代码)**:
|
||
```csharp
|
||
// 关键修复:完全避免使用ResetAllHidden,改用选择集策略
|
||
LogManager.Info("[FileExporter] 使用选择集策略替代可见性控制");
|
||
|
||
// 不再使用可见性控制,直接使用选择集方法
|
||
OnStatusChanged("正在设置选择集...");
|
||
|
||
// 清除当前选择
|
||
document.CurrentSelection.Clear();
|
||
|
||
// 设置要导出的元素为选中状态
|
||
document.CurrentSelection.AddRange(items);
|
||
```
|
||
|
||
#### B. 可见性恢复修复
|
||
**修复前**:
|
||
```csharp
|
||
document.Models.ResetAllHidden(); // 可能导致崩溃
|
||
```
|
||
|
||
**修复后**:
|
||
```csharp
|
||
// 只显示之前隐藏的元素,而不是重置所有
|
||
if (itemsToHide.Count > 0)
|
||
{
|
||
document.Models.SetHidden(itemsToHide, false);
|
||
LogManager.Info($"[FileExporter] 已恢复 {itemsToHide.Count} 个元素的可见性");
|
||
}
|
||
```
|
||
|
||
#### C. 异常处理修复
|
||
**修复前**:
|
||
```csharp
|
||
document.Models.ResetAllHidden(); // 异常处理中可能导致二次崩溃
|
||
```
|
||
|
||
**修复后**:
|
||
```csharp
|
||
// 关键修复:避免在异常处理中使用ResetAllHidden
|
||
LogManager.Error($"[FileExporter] 导出过程中发生异常: {ex.Message}");
|
||
LogManager.Info("[FileExporter] 跳过异常恢复中的可见性重置,避免二次崩溃");
|
||
|
||
// 只进行安全的清理操作
|
||
try
|
||
{
|
||
// 清除选择集是安全的
|
||
document.CurrentSelection.Clear();
|
||
LogManager.Info("[FileExporter] 异常恢复:已清除选择集");
|
||
}
|
||
catch (Exception safeEx)
|
||
{
|
||
LogManager.Warning($"[FileExporter] 异常恢复中的安全操作也失败: {safeEx.Message}");
|
||
}
|
||
```
|
||
|
||
## 🔄 新的工作策略
|
||
|
||
### 替代方案1:选择集策略
|
||
- 不再使用可见性控制
|
||
- 改用选择集来标识要导出的元素
|
||
- 通过 `document.CurrentSelection.AddRange(items)` 设置选择
|
||
|
||
### 替代方案2:安全的可见性操作
|
||
- 只使用 `SetHidden(collection, true/false)` 进行局部控制
|
||
- 避免使用 `ResetAllHidden()` 进行全局重置
|
||
- 只恢复之前隐藏的特定元素
|
||
|
||
### 替代方案3:错误容忍机制
|
||
- 所有可见性操作都包装在 try-catch 中
|
||
- 失败时记录日志但继续处理
|
||
- 提供多种备用策略
|
||
|
||
## 📊 修复效果预期
|
||
|
||
### 稳定性提升
|
||
- **崩溃率**: 从高频崩溃降至几乎为零
|
||
- **错误恢复**: 即使部分操作失败,程序也能继续运行
|
||
- **内存管理**: 避免了大量可见性操作导致的内存问题
|
||
|
||
### 性能优化
|
||
- **处理速度**: 减少了不必要的全局可见性重置
|
||
- **资源使用**: 降低了内存和CPU使用
|
||
- **响应性**: 减少了UI阻塞时间
|
||
|
||
### 用户体验改善
|
||
- **可靠性**: 分层拆分功能更加稳定
|
||
- **反馈**: 详细的日志记录便于问题诊断
|
||
- **容错性**: 部分失败不会影响整体操作
|
||
|
||
## 🧪 测试建议
|
||
|
||
### 测试步骤
|
||
1. **小型模型测试**:
|
||
- 使用简单的模型文件
|
||
- 验证基本分层功能
|
||
- 检查日志记录是否正常
|
||
|
||
2. **中型模型测试**:
|
||
- 使用包含多个楼层的模型
|
||
- 测试不同的分层策略
|
||
- 观察内存使用情况
|
||
|
||
3. **大型模型测试**:
|
||
- 使用复杂的建筑模型
|
||
- 分批处理,每批3-5个分层
|
||
- 监控系统稳定性
|
||
|
||
### 监控要点
|
||
- 查看日志中是否还有 `ResetAllHidden` 相关的崩溃
|
||
- 观察内存使用是否稳定
|
||
- 检查文件导出是否成功
|
||
- 验证可见性恢复是否正常
|
||
|
||
## 🚨 如果仍然出现问题
|
||
|
||
### 日志关键词搜索
|
||
在 `NavisworksTransport_Debug.log` 中搜索:
|
||
- `ERROR` - 查找错误信息
|
||
- `异常` - 查找异常情况
|
||
- `崩溃` - 查找崩溃相关信息
|
||
- `ResetAllHidden` - 检查是否还有遗漏的调用
|
||
|
||
### 备用策略
|
||
如果问题仍然存在,可以考虑:
|
||
1. **完全禁用可见性控制**:只使用选择集策略
|
||
2. **分批处理**:每次只处理1个分层
|
||
3. **重启策略**:每处理几个分层后重启Navisworks
|
||
|
||
## 📝 更新记录
|
||
|
||
- **v1.2** (2025-07-16): 修复 `ResetAllHidden()` 崩溃问题
|
||
- **v1.1** (2025-07-16): 增强日志记录和错误处理
|
||
- **v1.0** (2025-07-16): 初始版本
|
||
|
||
---
|
||
|
||
**现在请重新测试分层拆分功能!**
|
||
|
||
根据日志分析,崩溃问题应该已经完全解决。如果仍有问题,请立即查看最新的日志文件并提供相关信息。 |