开发者

How to ensure that clearing UIElementCollection immediately clears my control's children?

开发者 https://www.devze.com 2023-04-11 18:13 出处:网络
I have a Silverlight control which maintains a set of children. This set of children is quite rapidly updated during animations and a method that looks like this is called every time an animated depen

I have a Silverlight control which maintains a set of children. This set of children is quite rapidly updated during animations and a method that looks like this is called every time an animated dependency property on the control changes:

void SomeMethod(IEnumerable<ChildControlType> childControls)
{
    this.Children.Clear();
    foreach(var child in childControls)
    {
        this.Children.Add(c开发者_JS百科hild);
    }
}

What I'm seeing is a variable number of children on each frame, though it always converges to the required controls. That is, if, for every frame, I want 3 controls and send in an IEnumerable with 3 child controls, on most frames there are 3 children in the children collection at the end of this method. However, there are instances where at the end of of this method there are 12 controls, in the Children collection. This results in 12 controls being displayed in the control on some frames which looks ugly.

Can anyone explain why this would be?


How is SomeMethod being called in this example? It is possible that what you are seeing is due to multiple threads running the method concurrently.

I am by no means sure that this is the case, but you could test it by adding locking around your method:

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


Its difficult to be certain but it sounds like a re-entrancy problem to me (these days we worry much about "thread-safety" we often overlook the ancient problem of re-entrancy). Try this is tweak:-

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


I'm not sure why I didn't think of this before, but calling the SomeMethod method using the Dispatcher solves the issue.

This has slightly confused me because I thought that the changed callbacks for Dependency properties were always called on the Dispatcher's thread. I'm also not sure why the "lock" statement didn't have the same effect in this case. I might have some reading to do.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号