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 09:38:07 浏览: 16
可以将 `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);
}
}
```
这样就可以保证所有层级的遍历都能够完成,从而避免数据的丢失。
相关问题
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);在结构树第一层级全部遍历结束后就结束了等待,实际上其他层级遍历仍在进行,这造成了数据的大量丢失,请继续优化代码,并使用异步方式加快执行速度。
可以尝试使用`TaskCompletionSource`来替代`async void`,同时使用`Task<List<ModelItem>>`来返回结果:
```csharp
using Autodesk.Navisworks.Api;
using System.Collections.Generic;
using System.Threading.Tasks;
public static async Task<List<ModelItem>> GetAllNodesAsync()
{
List<ModelItem> nodes = new List<ModelItem>();
Document doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
ModelItemCollection rootItems = doc.Models.RootItemDescendants;
List<Task<List<ModelItem>>> tasks = new List<Task<List<ModelItem>>>();
foreach (ModelItem rootItem in rootItems)
{
tasks.Add(GetAllChildNodesAsync(rootItem));
}
var results = await Task.WhenAll(tasks);
foreach (var result in results)
{
nodes.AddRange(result);
}
return nodes;
}
private static Task<List<ModelItem>> GetAllChildNodesAsync(ModelItem parent)
{
var tcs = new TaskCompletionSource<List<ModelItem>>();
var nodes = new List<ModelItem>();
GetAllChildNodes(parent, nodes);
tcs.SetResult(nodes);
return tcs.Task;
}
private static void GetAllChildNodes(ModelItem parent, List<ModelItem> nodes)
{
nodes.Add(parent);
if (parent.Children.Count > 0)
{
foreach (ModelItem child in parent.Children)
{
GetAllChildNodes(child, nodes);
}
}
}
```
这样就可以保证在所有层级遍历结束后再返回结果。同时,使用`Task<List<ModelItem>>`可以更方便地在需要的时候获取异步操作的结果。
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> 中并返回。