using Autodesk.Navisworks.Api; using System.Collections.Generic; using System.Threading.Tasks; public static List<ModelItem> GetAllNodes() { List<ModelItem> nodes = new List<ModelItem>(); Document doc = Autodesk.Navisworks.Api.Application.ActiveDocument; ModelItemCollection rootItems = doc.Models.RootItemDescendants; foreach (ModelItem rootItem in rootItems) { GetAllChildNodes(rootItem, nodes); } return nodes; } private static async void GetAllChildNodes(ModelItem parent, List<ModelItem> nodes) { nodes.Add(parent); if (parent.Children.Count > 0) { List<Task> tasks = new List<Task>(); foreach (ModelItem child in parent.Children) { tasks.Add(Task.Run(() => GetAllChildNodes(child, nodes))); } await Task.WhenAll(tasks); } } 这段Navisworks二次开发代码中,await Task.WhenAll(tasks);在结构树第一层级全部遍历结束后就结束了等待,实际上其他层级遍历仍在进行,这造成了数据的大量丢失,请继续优化代码。
时间: 2024-03-26 20:38:07 浏览: 44
可以将 `GetAllChildNodes` 方法修改为同步方法,并在 `GetAllNodes` 方法中调用它,如下所示:
```csharp
public static List<ModelItem> GetAllNodes()
{
List<ModelItem> nodes = new List<ModelItem>();
Document doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
ModelItemCollection rootItems = doc.Models.RootItemDescendants;
foreach (ModelItem rootItem in rootItems)
{
GetAllChildNodes(rootItem, nodes);
}
return nodes;
}
private static void GetAllChildNodes(ModelItem parent, List<ModelItem> nodes)
{
nodes.Add(parent);
foreach (ModelItem child in parent.Children)
{
GetAllChildNodes(child, nodes);
}
}
```
这样就可以保证所有层级的遍历都能够完成,从而避免数据的丢失。
相关问题
Navisworks 二次开发,获取当前文档结构树全部节点,存储在list<ModelItem>里
Navisworks 提供了一组强大的 API,使得进行二次开发变得非常容易。以下是获取当前文档结构树全部节点,并将其存储在 list<ModelItem> 中的代码示例:
```csharp
using Autodesk.Navisworks.Api;
using System.Collections.Generic;
public static List<ModelItem> GetAllNodes()
{
List<ModelItem> nodes = new List<ModelItem>();
Document doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
// 获取当前文档结构树的根节点
ModelItemCollection rootItems = doc.Models.RootItemDescendants;
// 遍历根节点下的所有子节点
foreach (ModelItem item in rootItems)
{
// 将节点添加到列表中
nodes.Add(item);
// 如果当前节点有子节点,则递归获取所有子节点
if (item.Children.Count > 0)
{
List<ModelItem> childNodes = GetAllChildNodes(item);
nodes.AddRange(childNodes);
}
}
return nodes;
}
private static List<ModelItem> GetAllChildNodes(ModelItem parent)
{
List<ModelItem> childNodes = new List<ModelItem>();
// 遍历当前节点的所有子节点
foreach (ModelItem item in parent.Children)
{
// 将节点添加到列表中
childNodes.Add(item);
// 如果当前节点有子节点,则递归获取所有子节点
if (item.Children.Count > 0)
{
List<ModelItem> grandchildNodes = GetAllChildNodes(item);
childNodes.AddRange(grandchildNodes);
}
}
return childNodes;
}
```
以上代码将获取当前文档结构树的根节点,并递归获取所有子节点。将这些节点存储在 list<ModelItem> 中并返回。
Navisworks 二次开发,获取当前文档结构树全部节点,存储在list<ModelItem>里,要求执行速度要快,不能丢失数据。
如果需要在 Navisworks 的二次开发中获取文档结构树的全部节点,并且要求速度快、不丢失数据,可以考虑使用多线程来加速处理。
以下是基于多线程实现的代码示例:
```csharp
using Autodesk.Navisworks.Api;
using System.Collections.Generic;
using System.Threading.Tasks;
public static List<ModelItem> GetAllNodes()
{
List<ModelItem> nodes = new List<ModelItem>();
Document doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
// 获取当前文档结构树的根节点
ModelItemCollection rootItems = doc.Models.RootItemDescendants;
// 使用多线程遍历根节点下的所有子节点
Parallel.ForEach(rootItems, (rootItem) =>
{
// 将当前节点添加到列表中
lock (nodes)
{
nodes.Add(rootItem);
}
// 如果当前节点有子节点,则递归获取所有子节点
if (rootItem.Children.Count > 0)
{
List<ModelItem> childNodes = GetAllChildNodes(rootItem);
lock (nodes)
{
nodes.AddRange(childNodes);
}
}
});
return nodes;
}
private static List<ModelItem> GetAllChildNodes(ModelItem parent)
{
List<ModelItem> childNodes = new List<ModelItem>();
// 使用多线程遍历当前节点的所有子节点
Parallel.ForEach(parent.Children, (child) =>
{
// 将当前节点添加到列表中
lock (childNodes)
{
childNodes.Add(child);
}
// 如果当前节点有子节点,则递归获取所有子节点
if (child.Children.Count > 0)
{
List<ModelItem> grandchildNodes = GetAllChildNodes(child);
lock (childNodes)
{
childNodes.AddRange(grandchildNodes);
}
}
});
return childNodes;
}
```
在以上代码中,使用了 Parallel.ForEach 方法来同时遍历多个节点,从而提高遍历速度。同时,使用 lock 关键字来实现多线程之间对共享数据的同步,避免数据丢失。
阅读全文