我有一个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个控件,这些控件看起来很丑陋。
任何人都可以解释为什么会这样吗?
答案 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的线程上调用。我也不确定为什么“锁定”声明在这种情况下没有相同的效果。我可能有一些阅读要做。