如何通过并行循环优化节点的迭代?
How to optimize the iteration of nodes via parallel lop?
我有一个树列表中的节点列表。
有时我会关闭对列的排序,为了保持相同的 structure/position 节点,我会按原样复制结构,将其放入列表中,并在排序停用后完成我放回了节点位置。这是这样做的:
List<TreeListNode> nodes = new List<TreeListNode>();
nodes.AddRange(xtlItemList.Nodes);
// deactivete sorting
foreach (var c in xtlItemList.Columns) {
c.SortOrder = SortOrder.None;
}
// put back node positions
for (int i = 0; i < nodes.Count; i++)
{
xtlItemList.SetNodeIndex(nodes[i], i);
}
问题:
是不是第二个循环需要很多时间来执行。对于 1043 个节点,最多需要 50 秒。
我想我可以通过并行 for 循环优化它:
int counter = nodes.Count -1;
try
{
Parallel.For
(0
, counter
, new ParallelOptions { MaxDegreeOfParallelism = 5 }
, (i) =>
{
try
{
xtlItemList.SetNodeIndex(nodes[i], i);
}
catch (Exception exception)
{
//throw;
}
}
);
}
catch (Exception exx)
{
}
我得到了一些奇怪的结果。大多数情况下,ui 中的节点会消失,有时我会收到空引用异常,这让我更加困惑。
我在这里错过了什么?
我假设您在 Windows Forms 应用程序中使用 DevExpress XtraTreeList。
至于 parallel.for,它会在多个线程上执行,这与主 UI 线程不同。从非 UI 线程操作 UI 控件是不安全的,它会导致不可预知的结果:
Thread-safe calls to WPF controls
另外,我觉得并行循环也不会使它更快,因为进程不涉及后台工作。
我不是 DevExpress UI 控件的专家,但是对于您的实际问题,您可以创建一个额外的隐藏列,在您的 TreeList 中,用原始索引值(例如 1,2)填充它,3..) 并最初按此列对其节点进行排序。然后稍后您可以按照此处的建议再次恢复您的 XtraTreeList 按此列排序:
我想这会工作得更快。
希望这有助于解决您的问题..
原来 Devexpress 有 BeginUpdate()
和 EndUpdate()
方法。
我使用了这些,它们大大优化了我的树渲染。修改后的解决方案:
我现在有:
而不是并行
xtlItemList.BeginUpdate();
for (int i = 0; i < nodes.Count; i++)
{
xtlItemList.SetNodeIndex(nodes[i], i);
}
xtlItemList.EndUpdate();
文档:
我有一个树列表中的节点列表。
有时我会关闭对列的排序,为了保持相同的 structure/position 节点,我会按原样复制结构,将其放入列表中,并在排序停用后完成我放回了节点位置。这是这样做的:
List<TreeListNode> nodes = new List<TreeListNode>();
nodes.AddRange(xtlItemList.Nodes);
// deactivete sorting
foreach (var c in xtlItemList.Columns) {
c.SortOrder = SortOrder.None;
}
// put back node positions
for (int i = 0; i < nodes.Count; i++)
{
xtlItemList.SetNodeIndex(nodes[i], i);
}
问题:
是不是第二个循环需要很多时间来执行。对于 1043 个节点,最多需要 50 秒。
我想我可以通过并行 for 循环优化它:
int counter = nodes.Count -1;
try
{
Parallel.For
(0
, counter
, new ParallelOptions { MaxDegreeOfParallelism = 5 }
, (i) =>
{
try
{
xtlItemList.SetNodeIndex(nodes[i], i);
}
catch (Exception exception)
{
//throw;
}
}
);
}
catch (Exception exx)
{
}
我得到了一些奇怪的结果。大多数情况下,ui 中的节点会消失,有时我会收到空引用异常,这让我更加困惑。
我在这里错过了什么?
我假设您在 Windows Forms 应用程序中使用 DevExpress XtraTreeList。
至于 parallel.for,它会在多个线程上执行,这与主 UI 线程不同。从非 UI 线程操作 UI 控件是不安全的,它会导致不可预知的结果:
Thread-safe calls to WPF controls
另外,我觉得并行循环也不会使它更快,因为进程不涉及后台工作。
我不是 DevExpress UI 控件的专家,但是对于您的实际问题,您可以创建一个额外的隐藏列,在您的 TreeList 中,用原始索引值(例如 1,2)填充它,3..) 并最初按此列对其节点进行排序。然后稍后您可以按照此处的建议再次恢复您的 XtraTreeList 按此列排序:
我想这会工作得更快。
希望这有助于解决您的问题..
原来 Devexpress 有 BeginUpdate()
和 EndUpdate()
方法。
我使用了这些,它们大大优化了我的树渲染。修改后的解决方案:
我现在有:
而不是并行 xtlItemList.BeginUpdate();
for (int i = 0; i < nodes.Count; i++)
{
xtlItemList.SetNodeIndex(nodes[i], i);
}
xtlItemList.EndUpdate();
文档: