如何确保清除UIElementCollection立即清除我控制的孩子?

时间:2011-10-07 17:31:36

标签: silverlight

我有一个Silverlight控件,它维护着一组孩子。这组子项在动画期间非常快速地更新,并且每当控件上的动画依赖项属性发生更改时,就会调用这样的方法:

void SomeMethod(IEnumerable<ChildControlType> childControls)
{
    this.Children.Clear();
    foreach(var child in childControls)
    {
        this.Children.Add(child);
    }
}

我所看到的是每帧上有不同数量的孩子,尽管它总是收敛到所需的控件。也就是说,如果,对于每一帧,我想要3个控件并发送带有3个子控件的IEnumerable,在大多数帧上,在此方法结束时子集合中有3个子节点。但是,有些情况下,在此方法的最后,在Children集合中有12个控件。这导致在控件上显示12个控件,这些控件看起来很丑陋。

任何人都可以解释为什么会这样吗?

3 个答案:

答案 0 :(得分:0)

在此示例中如何调用SomeMethod?您所看到的可能是由于多个线程同时运行该方法。

我不确定是这种情况,但您可以通过在方法周围添加锁定来测试它:

private volatile object _lockObject = new object();

void SomeMethod(IEnumerable<ChildControlType> childControls)
{
    lock (_lockObject)
    {
         this.Children.Clear();
         foreach(var child in childControls)
         {
             this.Children.Add(child);
         }
    }
}

答案 1 :(得分:0)

很难确定它,但这听起来像是一个重新入侵的问题(现在我们担心“线程安全”,我们常常忽略了古老的重新入侵问题)。试试这是调整: -

bool inSomeMethod = false
void SomeMethod(IEnumerable<ChildControlType> childControls) 
{ 
    if (!inSomeMethod)
    {
        inSomeMethod = true;
        this.Children.Clear(); 
        foreach(var child in childControls) 
        { 
            this.Children.Add(child); 
        }
        inSomeMethod = false;
    } 
}

答案 2 :(得分:0)

我不确定为什么我之前没有想到这一点,但使用Dispatcher调用SomeMethod方法可以解决问题。

这让我有点困惑,因为我认为Dependency属性的更改回调总是在Dispatcher的线程上调用。我也不确定为什么“锁定”声明在这种情况下没有相同的效果。我可能有一些阅读要做。