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 18:38:17 浏览: 197
可以尝试使用`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>>`可以更方便地在需要的时候获取异步操作的结果。
阅读全文