NavisworksTransport/doc/guide/crash_prevention_guide.md

229 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Navisworks分层拆分崩溃问题解决指南
## 问题描述
在使用模型分层拆分功能时Navisworks程序在分层预览后开始运行分层时发生崩溃。
## 根本原因分析
经过代码分析,崩溃的主要原因包括:
1. **内存管理问题**:大量的可见性状态操作导致内存泄漏
2. **线程安全问题**异步操作与Navisworks UI线程冲突
3. **COM对象释放问题**Navisworks API的COM对象没有正确释放
4. **文档状态不一致**:导出过程中文档状态被意外修改
5. **递归深度过深**:在检查模型层次结构时可能导致栈溢出
## 已实施的解决方案
### 1. 优化可见性控制策略
**修改前的问题**
- 遍历所有模型元素进行可见性操作
- 保存和恢复复杂的可见性状态
- 大量的SetHidden操作导致内存压力
**修改后的改进**
```csharp
// 使用简化的可见性控制策略
document.Models.ResetAllHidden(); // 从干净状态开始
// 只处理顶层元素,减少操作量
var rootItems = document.Models.SelectMany(model => model.RootItem.Children).ToList();
// 只隐藏不包含目标元素的顶层分支
foreach (var rootItem in rootItems)
{
if (!ContainsAnyTargetItem(rootItem, items))
{
itemsToHide.Add(rootItem);
}
}
```
### 2. 增强错误恢复机制
**新增功能**
- 每个分层处理前确保Navisworks处于稳定状态
- 处理失败时自动恢复文档状态
- 连续失败检测和自动停止机制
- 定期垃圾回收释放内存
```csharp
// 确保稳定状态
private void EnsureStableState()
{
var document = NavisApplication.ActiveDocument;
if (document != null)
{
document.Models.ResetAllHidden();
document.CurrentSelection.Clear();
System.Threading.Thread.Sleep(100);
}
}
// 错误恢复
private void RecoverFromError()
{
var document = NavisApplication.ActiveDocument;
if (document != null)
{
document.Models.ResetAllHidden();
document.CurrentSelection.Clear();
document.ActiveView.RequestDelayedRedraw(ViewRedrawRequests.All);
}
GC.Collect();
}
```
### 3. 改进文件保存机制
**新增重试机制**
- 最多3次保存重试
- 每次重试前等待递增时间
- 验证保存文件的完整性
- 自动清理失败的临时文件
```csharp
// 重试保存逻辑
int retryCount = 0;
const int maxRetries = 3;
while (!success && retryCount < maxRetries)
{
try
{
retryCount++;
// 确保文档状态稳定
System.Threading.Thread.Sleep(100);
// 执行保存操作
document.SaveFile(outputPath);
// 验证文件完整性
if (File.Exists(outputPath))
{
var fileInfo = new FileInfo(outputPath);
success = fileInfo.Length > 0;
}
}
catch (Exception ex)
{
if (retryCount < maxRetries)
{
System.Threading.Thread.Sleep(retryCount * 1000);
}
}
}
```
### 4. 优化递归算法
**防止栈溢出**
- 限制递归深度为10层
- 添加异常处理保护
- 使用保守的错误处理策略
```csharp
private bool ContainsAnyTargetItemRecursive(ModelItem item, ModelItemCollection targetItems,
int currentDepth, int maxDepth)
{
// 防止递归过深
if (currentDepth > maxDepth)
{
return false;
}
// 安全的递归检查逻辑
// ...
}
```
## 使用建议
### 1. 操作前准备
- 确保有足够的系统内存建议8GB以上
- 关闭不必要的其他应用程序
- 保存当前工作,以防意外情况
### 2. 分层策略选择
- **小型模型**<1000个元素可以使用任何策略
- **中型模型**1000-10000个元素推荐使用"按楼层""按类别"
- **大型模型**>10000个元素建议分批处理每批不超过5个分层
### 3. 输出设置优化
- 选择本地磁盘作为输出目录(避免网络路径)
- 确保输出目录有足够的磁盘空间
- 建议关闭"生成报告"选项以提高性能
### 4. 监控和处理
- 观察内存使用情况,如果内存使用过高请暂停操作
- 如果出现连续失败请重启Navisworks后再试
- 保持Navisworks窗口可见避免最小化
## 故障排除
### 如果仍然发生崩溃
1. **检查模型复杂度**
- 模型元素数量是否过多
- 是否存在损坏的几何体
- 属性数据是否完整
2. **系统环境检查**
- 更新Navisworks到最新版本
- 检查.NET Framework版本
- 确认系统内存充足
3. **分批处理**
- 将大型分层任务分解为多个小任务
- 每处理几个分层后重启Navisworks
- 使用"预览"功能验证分层结果
### 紧急恢复步骤
如果Navisworks崩溃
1. 重启Navisworks
2. 重新打开原始模型文件
3. 检查已生成的分层文件
4. 从失败的分层开始继续处理
## 性能优化建议
1. **内存管理**
- 定期重启Navisworks释放内存
- 关闭不需要的视图和面板
- 避免同时打开多个大型模型
2. **处理策略**
- 优先处理简单的分层
- 将复杂分层留到最后处理
- 考虑使用"按类别"策略减少复杂度
3. **系统配置**
- 增加虚拟内存设置
- 关闭不必要的后台程序
- 使用SSD硬盘提高I/O性能
## 更新日志
- **v1.0** (2024-12-19): 初始版本,解决基本崩溃问题
- **v1.1** (2024-12-19): 增加错误恢复机制和重试逻辑
- **v1.2** (2024-12-19): 优化内存管理和递归算法
## 技术支持
如果问题仍然存在,请提供以下信息:
1. Navisworks版本信息
2. 模型文件大小和复杂度
3. 系统配置内存、CPU等
4. 具体的错误信息或崩溃日志
5. 重现问题的具体步骤
通过这些改进,分层拆分功能的稳定性应该得到显著提升。