A canvas control is frozen


Working with Visual Studio 2015, WPF I have a Canvas control which serves as a canvas to draw a skeleton that I get by scanning through the Kinect device when I get in front of the device my skeleton that appears on the canvas freezes.

I tried using async / await using task to prevent it from freezing, this is the code I occupy.

        await Task.Run(() => skeletonCanvas.Children.Clear());
                    await Task.Run(() => skeletonCanvas.Children.Add(jointLine));

Code of the entire event

private async void KSensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
        string manoDerecha = string.Empty;
        string manoIzquierda = string.Empty;
        Skeleton[] skeletons;
        using (var frame = e.OpenSkeletonFrame())
            if (frame == null) return;
            skeletons = new Skeleton[frame.SkeletonArrayLength];

        int iSkeleton = 0;
        var brushes = new Brush[6];
        brushes[0] = new SolidColorBrush(Color.FromRgb(255, 0, 0));
        brushes[1] = new SolidColorBrush(Color.FromRgb(0, 255, 0));
        brushes[2] = new SolidColorBrush(Color.FromRgb(64, 255, 255));
        brushes[3] = new SolidColorBrush(Color.FromRgb(255, 255, 64));
        brushes[4] = new SolidColorBrush(Color.FromRgb(255, 64, 255));
        brushes[5] = new SolidColorBrush(Color.FromRgb(128, 128, 255));

        await Task.Run(() => skeletonCanvas.Children.Clear());
        foreach (var data in skeletons)
            if (SkeletonTrackingState.Tracked == data.TrackingState)
                Joint jointManoDerecha = data.Joints[JointType.HandRight];
                Joint jointManoIzquierda = data.Joints[JointType.HandLeft];

                SkeletonPoint posicionManoDerecha = jointManoDerecha.Position;
                SkeletonPoint posicionManoIzquierda = jointManoIzquierda.Position;

                manoDerecha = string.Format("Mano derecha: X:{0:0.0} Y:{1:0.0} Z{2:0.0}", posicionManoDerecha.X, posicionManoDerecha.Y, 

                manoIzquierda = string.Format("Mano izquierda: X:{0:0.0} Y:{1:0.0} Z{2:0.0}", posicionManoIzquierda.X, posicionManoIzquierda.Y,

                // Dibujar huesos
                Brush brush = brushes[iSkeleton % brushes.Length];
                skeletonCanvas.Children.Add(GetBodySegment(data.Joints, brush, JointType.HipCenter, JointType.Spine, JointType.ShoulderCenter, JointType.Head));
                skeletonCanvas.Children.Add(GetBodySegment(data.Joints, brush, JointType.ShoulderCenter, JointType.ShoulderLeft, JointType.ElbowLeft, JointType.WristLeft, JointType.HandLeft));
                skeletonCanvas.Children.Add(GetBodySegment(data.Joints, brush, JointType.ShoulderCenter, JointType.ShoulderRight, JointType.ElbowRight, JointType.WristRight, JointType.HandRight));
                skeletonCanvas.Children.Add(GetBodySegment(data.Joints, brush, JointType.HipCenter, JointType.HipLeft, JointType.KneeLeft, JointType.AnkleLeft, JointType.FootLeft));
                skeletonCanvas.Children.Add(GetBodySegment(data.Joints, brush, JointType.HipCenter, JointType.HipRight, JointType.KneeRight, JointType.AnkleRight, JointType.FootRight));

                // Dibujar articulaciones
                foreach (Joint joint in data.Joints)
                    Point jointPos = GetDisplayPosition(joint);
                    var jointLine = new Line();
                    jointLine.X1 = jointPos.X - 3;
                    jointLine.X2 = jointLine.X1 + 6;
                    jointLine.Y1 = jointLine.Y2 = jointPos.Y;
                    jointLine.Stroke = _jointColors[joint.JointType];
                    jointLine.StrokeThickness = 6;
                    await Task.Run(() => skeletonCanvas.Children.Add(jointLine));

        } // para cada esqueleto
        lblManoDerecha.Content = manoDerecha;
        lblManoIzquierda.Content = manoIzquierda;

The error he gives me is this:


The subprocess making the call can not access this   object because the owner is another subprocess.

asked by Pedro Ávila 09.11.2017 в 22:23

1 answer


Control manipulation can not be done from another thread. Those operations must remain in the main thread, the UI thread.

The use of tasks is to do heavy work that takes a long time, and allow it to be done in a different thread so that the UI thread is released and can continue to handle the interface without freezing. But this heavy work should not include interface manipulation. It can only include things like calls to the database, heavy calculations, etc.

So that your interface does not freeze, you must identify which portions of your code, which do not involve the controls , take a long time, and those can use tasks to free the UI thread. p>     

answered by 09.11.2017 / 22:36