NavisworksTransport/doc/guide/crash_prevention_guide.md

5.8 KiB
Raw Blame History

Navisworks分层拆分崩溃问题解决指南

问题描述

在使用模型分层拆分功能时Navisworks程序在分层预览后开始运行分层时发生崩溃。

根本原因分析

经过代码分析,崩溃的主要原因包括:

  1. 内存管理问题:大量的可见性状态操作导致内存泄漏
  2. 线程安全问题异步操作与Navisworks UI线程冲突
  3. COM对象释放问题Navisworks API的COM对象没有正确释放
  4. 文档状态不一致:导出过程中文档状态被意外修改
  5. 递归深度过深:在检查模型层次结构时可能导致栈溢出

已实施的解决方案

1. 优化可见性控制策略

修改前的问题

  • 遍历所有模型元素进行可见性操作
  • 保存和恢复复杂的可见性状态
  • 大量的SetHidden操作导致内存压力

修改后的改进

// 使用简化的可见性控制策略
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处于稳定状态
  • 处理失败时自动恢复文档状态
  • 连续失败检测和自动停止机制
  • 定期垃圾回收释放内存
// 确保稳定状态
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次保存重试
  • 每次重试前等待递增时间
  • 验证保存文件的完整性
  • 自动清理失败的临时文件
// 重试保存逻辑
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层
  • 添加异常处理保护
  • 使用保守的错误处理策略
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. 重现问题的具体步骤

通过这些改进,分层拆分功能的稳定性应该得到显著提升。