private void OnThreadCSwitch(CSwitchTraceData data)
        {
            // Start blocking on the old thread.
            // Ignore the idle thread.
            if (data.OldThreadID != 0)
            {
                TraceThread oldThread = m_Configuration.TraceLog.Threads.GetThread(data.OldThreadID, data.TimeStampRelativeMSec);
                if (null != oldThread)
                {
                    ComputingResourceThreadState oldThreadState = m_ThreadState[(int)oldThread.ThreadIndex];
                    oldThreadState.LogBlockingStart(this, oldThread, data);
                }
            }

            // Stop blocking on the new thread.
            // Ignore the idle thread.
            if (data.ThreadID != 0)
            {
                TraceThread newThread = data.Thread();
                if (null != newThread)
                {
                    ComputingResourceThreadState newThreadState = m_ThreadState[(int)newThread.ThreadIndex];
                    newThreadState.LogBlockingStop(this, newThread, data);
                }
            }
        }
        private void OnThreadStart(ThreadTraceData data)
        {
            TraceThread thread = data.Thread();

            Debug.Assert(thread != null);
            if (null == thread)
            {
                return;
            }

            // Get the thread state.
            ComputingResourceThreadState threadState = m_ThreadState[(int)thread.ThreadIndex];

            // Mark that blocking has started.
            threadState.LogBlockingStart(this, thread, data);
        }