2011-10-07 60 views
1

我有一个Silverlight控件,它维护一组子对象。这组儿童的动画中相当迅速更新,看起来像这样的方法被称为每次在控制变化的动画依赖属性:如何确保清除UIElementCollection立即清除我的控件的子项?

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

我所看到的是孩子的可变数量上的每个框架,尽管它总是汇聚到所需的控制。也就是说,如果对于每一帧,我想要3个控件并发送带有3个子控件的IEnumerable,则在大多数帧上,在此方法结束时,子集中会有3个子元素。但是,有些情况下,在该方法的最后,在Children集合中有12个控件。这导致12个控件显示在控件上,看起来很丑陋。

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

回答

0

我不知道为什么我没有想到之前的这一点,但调用使用调度员的someMethod方法解决这个问题。

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

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); 
     } 
    } 
} 
+0

是的。我已经试过这个机会。它不起作用。实际上对方法的调用总是来自DependencyProperty的改变的回调。据我了解,这个回调总是在UI线程上调用它不是吗? –

+0

我怀疑是这样,但值得一试。在那种情况下,我会假设孩子的加入不是同步的。也许你可以隐藏/显示而不是添加/删除? –

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; 
    } 
}