Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么锁在这种情况下不起作用?_C#_Multithreading_Locking - Fatal编程技术网

C# 为什么锁在这种情况下不起作用?

C# 为什么锁在这种情况下不起作用?,c#,multithreading,locking,C#,Multithreading,Locking,正如您所见,BodySource在另一个线程中得到更新,并同时更新BodyRefiner。主体细化器包含一个从主循环调用的getBodys方法。CopyBody和GetBody中的调试日志不会记录相同的结果。如果在这两种方法中都使用lock语句,怎么会出现这种情况?CopyBody在记录之前更改copiedBodies成员,因此如果在CopyBody之前调用GetBody,您将获得不同的日志,由于GetBody将记录旧成员,CopyBody将记录新成员。我刚刚制作了Body数组的深度副本,因此每

正如您所见,BodySource在另一个线程中得到更新,并同时更新BodyRefiner。主体细化器包含一个从主循环调用的getBodys方法。CopyBody和GetBody中的调试日志不会记录相同的结果。如果在这两种方法中都使用lock语句,怎么会出现这种情况?

CopyBody在记录之前更改copiedBodies成员,因此如果在CopyBody之前调用GetBody,您将获得不同的日志,由于GetBody将记录旧成员,CopyBody将记录新成员。

我刚刚制作了Body数组的深度副本,因此每次编辑它时,我的copiedBodies数组也会更改。因为我的UpdateBodies方法中没有锁,所以我遇到了这些同步错误

能否显示用于调用此方法的线程片段?能否共享locker对象的声明方式?您没有提供足够的代码来复制此问题。缺少的东西太多了。您正在访问其他地方使用的数据,而没有显示其他哪些数据正在接触相同的数据;我刚刚看过代码,CopyBodys方法完成后,CopyBodys IsTracket字段始终为false。而且复制体仅在复制体中修改,因此不能作为解决方案。
     public class BodyRefiner
    {
        private KinectBody[] bodies = new KinectBody[6];
        private KinectBody[] copiedBodies = new KinectBody[6];

        public static readonly object locker = new object();

        BodyDirectionCalculator directionCalculator;
        JointOrientationCalculator orientationCalculator;
        private BodyManipulator manipulator;

        public BodyRefiner()
        {
            directionCalculator = new BodyDirectionCalculator();
            orientationCalculator = new JointOrientationCalculator();
        }

        public void AttachBodyManipulator(BodyManipulator manipulatorToAttach)
        {
            this.manipulator = manipulatorToAttach;
        }

        public void DettachBodyManipulator()
        {
            this.manipulator = null;
        }

        public void UpdateBodies(Body[] acquiredBodies)
        {
            for(int i = 0; i < acquiredBodies.Length; i++)
            {
                this.bodies[i] = new KinectBody(acquiredBodies[i]);
                directionCalculator.CalculateDirections(ref this.bodies[i]);
                orientationCalculator.CalculateJointOrientations(ref this.bodies[i]);
            }
            CopyBodies();
        }

        public KinectBody[] GetBodies()
        {
            lock(locker)
            {
                foreach(KinectBody b in copiedBodies)
                {
                    Debug.Log(b.isTracked);
                }
                return copiedBodies;
            }
        }

        private void CopyBodies()
        {
            lock (locker)
            {
                copiedBodies = bodies;

                if (manipulator != null)
                {
                    copiedBodies = manipulator.GetManipulatedBodies(copiedBodies);
                }

                foreach (KinectBody b in copiedBodies)
                {
                    Debug.Log(b.isTracked);
                }
            }
        }
    }

 public class BodySource : Singleton<BodySource>
    {
        private Body[] bodies;
        private KinectSensor sensor;
        private BodyFrameReader reader;
        public BodyRefiner contributor;
        private Thread worker;

        void Awake()
        {
            base.Awake();

            sensor = KinectSensor.GetDefault();

            if (!sensor.IsOpen)
            {
                sensor.Open();
            }

            BodyFrameSource source = sensor.BodyFrameSource;
            reader = source.OpenReader();
            bodies = new Body[source.BodyCount];

            contributor = new BodyRefiner();

            worker = new Thread(AcquireBodyFrame);
            worker.Start();
        }

        void AcquireBodyFrame()
        {
            if (reader != null)
            {
                using (var frame = reader.AcquireLatestFrame())
                {
                    if (frame != null)
                    {
                        frame.GetAndRefreshBodyData(bodies);
                        frame.Dispose();
                        contributor.UpdateBodies(bodies);
                    }
                }
            }

            Thread.Sleep(1000 / 30);
            AcquireBodyFrame();
        }

        void OnApplicationQuit()
        {
            worker.Abort();
            worker = null;
        }
    }
public class CustomTrackingTryFullChar : MonoBehaviour {
    private Transform[] bones;
    private Quaternion[] initialRotations;
    public Animator animator;
    private Quaternion initRot;
    private Alpaca.Kinect.KinectGameComponent comp;
    public TrackingMask mask;
    public float smoothFactor;
    KinectTest.KinectBody b;
    Transform boneTransform;
    Quaternion jointRotation;
    KinectTest.KinectBody[] trackedBodies;

    // Use this for initialization
    void Start () {
        bones = new Transform[27];
        MapBones();
        initialRotations = new Quaternion[bones.Length];
        GetInitialRotations();
        comp = GetComponent<Alpaca.Kinect.KinectGameComponent>();

        KinectTest.BodyManipulator manipulator = new KinectTest.BodyManipulator();
        manipulator.wantedAmountOfTrackedBodies = 0;
        KinectTest.BodySource.Instance.contributor.AttachBodyManipulator(manipulator);
    }

    private void MapBones()
    {
        for (int boneIndex = 0; boneIndex < bones.Length; boneIndex++)
        {
            if (!BoneMaps.boneIndex2MecanimMap.ContainsKey(boneIndex))
                continue;

            bones[boneIndex] = this.animator.GetBoneTransform(BoneMaps.boneIndex2MecanimMap[boneIndex]);
        }
    }

    private void GetInitialRotations()
    {
        Quaternion temp = this.transform.rotation;
        this.transform.rotation = Quaternion.identity;

        for (int i = 0; i < bones.Length; i++)
        {
            if (bones[i] != null)
            {
                initialRotations[i] = bones[i].rotation;
            }
        }

        this.transform.rotation = temp;
    }

    // Update is called once per frame
    void Update () {
        trackedBodies = KinectTest.BodySource.Instance.contributor.GetBodies();
        foreach (KinectTest.KinectBody bd in trackedBodies)
        {
            if (bd.isTracked)
            {
                b = bd;
                TransformBones();
            }
        }
    }

    bool IsJointTracked(KinectTest.KinectJoint joint)
    {
        return joint.trackingState == TrackingState.Tracked;
    }

    bool ShallJointBeTracked(JointType type)
    {
        return mask.TrackJoint(type);
    }


    void TransformBones()
    {
        for (int boneIndex = 0; boneIndex < bones.Length; boneIndex++)
        {
            if (!bones[boneIndex])
            {
                continue;
            }

            if (BoneMaps.boneIndex2JointMap.ContainsKey(boneIndex))
            {
                JointType joint = BoneMaps.boneIndex2JointMap[boneIndex];
                TransformBone(joint, boneIndex, null, b.joints);
            }
        }
    }

    private void TransformBone(JointType joint, int boneIndex, Dictionary<JointType, Quaternion> orientations, Dictionary<JointType, KinectTest.KinectJoint> joints)
    {
        boneTransform = bones[boneIndex];
        if (boneTransform == null)
        {
            return;
        }
        int iJoint = (int)joint;
        if (iJoint < 0 || !this.IsJointTracked(b.joints[joint]) || !ShallJointBeTracked(joint))
        {
            return;
        }

        // Get Kinect joint orientation
        jointRotation = Quaternion.identity;

        if (b.isTracked)
        {
            jointRotation = b.joints[joint].rotation;
        }

        if (jointRotation == Quaternion.identity)
            return;

        Kinect2AvatarRot(jointRotation, boneIndex);
        if (smoothFactor != 0f)
        {
            boneTransform.rotation = Quaternion.Slerp(boneTransform.rotation, newRotation, smoothFactor * Time.deltaTime);
        }
        else
        {
            boneTransform.rotation = newRotation;
        }
    }

    Quaternion newRotation;
    Vector3 totalRotation;
    private Quaternion Kinect2AvatarRot(Quaternion jointRotation, int boneIndex)
    {
        newRotation = jointRotation * initialRotations[boneIndex];

        totalRotation = newRotation.eulerAngles + this.transform.rotation.eulerAngles;
        newRotation = Quaternion.Euler(totalRotation);

        return newRotation;
    }


}