/// <summary>
        /// Gets WCT information using WCT api by the given threadId (OS threadId)
        /// </summary>
        /// <param name="threadId"> ThreadWCTInfo  object</param>
        /// <returns>Thread id of thread target</returns>
        public ThreadWCTInfo GetBlockingObjects(uint threadId)
        {
            ThreadWCTInfo result = null;

            var g_WctIntPtr = Functions.OpenThreadWaitChainSession((int)WCT_SESSION_OPEN_FLAGS.WCT_SYNC_OPEN_FLAG, 0);

            WAITCHAIN_NODE_INFO[] NodeInfoArray = new WAITCHAIN_NODE_INFO[Const.WCT_MAX_NODE_COUNT];

            int isCycle = 0;
            int Count = Const.WCT_MAX_NODE_COUNT;

            // Make a synchronous WCT call to retrieve the wait chain.
            bool waitChainResult = Functions.GetThreadWaitChain(g_WctIntPtr,
                                    IntPtr.Zero,
                                    Const.WCTP_GETINFO_ALL_FLAGS,
                                    threadId, ref Count, NodeInfoArray, out isCycle);

            CheckCount(ref Count);

            if (waitChainResult)
            {
                result = HandleGetThreadWaitChainRsult(threadId, Count, NodeInfoArray, isCycle);
            }
            else
            {
                HandleWctRequestError();
            }

            //Finaly ...
            Functions.CloseThreadWaitChainSession(g_WctIntPtr);

            return result;
        }
        public WaitChainInfoObject(WAITCHAIN_NODE_INFO item)
        {
            ObjectStatus = item.ObjectStatus;
            ObjectType = item.ObjectType;

            //LockObject stuct data
            TimeOut = item.Union.LockObject.Timeout;
            AlertTable = item.Union.LockObject.Alertable;

            if (item.ObjectType == WCT_OBJECT_TYPE.WctThreadType)
            { //Use the ThreadObject part of the union
                this.ThreadId = item.Union.ThreadObject.ThreadId;
                this.ProcessId = item.Union.ThreadObject.ProcessId;
                this.ContextSwitches = item.Union.ThreadObject.ContextSwitches;
                this.WaitTime = item.Union.ThreadObject.WaitTime;

            }
            else
            {//Use the LockObject  part of the union
                unsafe
                {
                    ObjectName = Marshal.PtrToStringUni((IntPtr)item.Union.LockObject.ObjectName);
                }
            }
        }
        private ThreadWCTInfo HandleGetThreadWaitChainRsult(uint threadId, int Count, WAITCHAIN_NODE_INFO[] NodeInfoArray, int isCycle)
        {
            ThreadWCTInfo result = new ThreadWCTInfo(isCycle == 1, threadId);
            WAITCHAIN_NODE_INFO[] info = new WAITCHAIN_NODE_INFO[Count];
            Array.Copy(NodeInfoArray, info, Count);

            result.SetInfo(info);

            return result;
        }
 internal void SetInfo(WAITCHAIN_NODE_INFO[] info)
 {
     if (info != null)
     {
         foreach (var item in info)
         {
             var block = new WaitChainInfoObject(item);
             WctBlockingObjects.Add(block);
         }
     }
 }