private TraceEventNativeMethods.EVENT_RECORD *ReadEvent(PinnedStreamReader reader)
        {
            // Guess that the event is < 1000 bytes or whatever is left in the stream.
            int eventSizeGuess = Math.Min(1000, _endOfEventStream.Sub(reader.Current));
            EventPipeEventHeader *eventData = (EventPipeEventHeader *)reader.GetPointer(eventSizeGuess);

            // Basic sanity checks.  Are the timestamps and sizes sane.
            Debug.Assert(sessionEndTimeQPC <= eventData->TimeStamp);
            Debug.Assert(sessionEndTimeQPC == 0 || eventData->TimeStamp - sessionEndTimeQPC < _QPCFreq * 24 * 3600);
            Debug.Assert(0 <= eventData->PayloadSize && eventData->PayloadSize <= eventData->TotalEventSize);
            Debug.Assert(eventData->MetaDataId <= reader.Current);                              // IDs are the location in the of of the data, so it comes before
            Debug.Assert(0 < eventData->TotalEventSize && eventData->TotalEventSize < 0x20000); // TODO really should be 64K but BulkSurvivingObjectRanges needs fixing.

            if (eventSizeGuess < eventData->TotalEventSize)
            {
                eventData = (EventPipeEventHeader *)reader.GetPointer(eventData->TotalEventSize);
            }

            Debug.Assert(0 <= EventPipeEventHeader.StackBytesSize(eventData) && EventPipeEventHeader.StackBytesSize(eventData) <= eventData->TotalEventSize);
            // This asserts that the header size + payload + stackSize field + StackSize == TotalEventSize;
            Debug.Assert(eventData->PayloadSize + EventPipeEventHeader.HeaderSize + sizeof(int) + EventPipeEventHeader.StackBytesSize(eventData) == eventData->TotalEventSize);

            TraceEventNativeMethods.EVENT_RECORD *ret = null;
            EventPipeEventMetaData metaData;

            if (eventData->MetaDataId == 0)     // Is this a Meta-data event?
            {
                int         totalEventSize       = eventData->TotalEventSize;
                int         payloadSize          = eventData->PayloadSize;
                StreamLabel metaDataStreamOffset = reader.Current;  // Used as the 'id' for the meta-data
                // Note that this skip invalidates the eventData pointer, so it is important to pull any fields out we need first.
                reader.Skip(EventPipeEventHeader.HeaderSize);
                metaData = new EventPipeEventMetaData(reader, payloadSize, _fileFormatVersionNumber, PointerSize, _processId);
                _eventMetadataDictionary.Add(metaDataStreamOffset, metaData);
                _eventParser.AddTemplate(metaData);
                int stackBytes = reader.ReadInt32();        // Meta-data events should always have a empty stack.
                Debug.Assert(stackBytes == 0);

                // We have read all the bytes in the event
                Debug.Assert(reader.Current == metaDataStreamOffset.Add(totalEventSize));
            }
            else
            {
                if (_eventMetadataDictionary.TryGetValue(eventData->MetaDataId, out metaData))
                {
                    ret = metaData.GetEventRecordForEventData(eventData);
                }
                else
                {
                    Debug.Assert(false, "Warning can't find metaData for ID " + eventData->MetaDataId.ToString("x"));
                }
                reader.Skip(eventData->TotalEventSize);
            }

            return(ret);
        }
        internal TraceEventNativeMethods.EVENT_RECORD *ReadEvent(PinnedStreamReader reader)
        {
            EventPipeEventHeader *eventData = (EventPipeEventHeader *)reader.GetPointer(EventPipeEventHeader.HeaderSize);

            eventData = (EventPipeEventHeader *)reader.GetPointer(eventData->TotalEventSize); // now we now the real size and get read entire event

            // Basic sanity checks.  Are the timestamps and sizes sane.
            Debug.Assert(sessionEndTimeQPC <= eventData->TimeStamp);
            Debug.Assert(sessionEndTimeQPC == 0 || eventData->TimeStamp - sessionEndTimeQPC < _QPCFreq * 24 * 3600);
            Debug.Assert(0 <= eventData->PayloadSize && eventData->PayloadSize <= eventData->TotalEventSize);
            Debug.Assert(0 < eventData->TotalEventSize && eventData->TotalEventSize < 0x20000);                               // TODO really should be 64K but BulkSurvivingObjectRanges needs fixing.
            Debug.Assert(_fileFormatVersionNumber < 3 ||
                         ((int)EventPipeEventHeader.PayloadBytes(eventData) % 4 == 0 && eventData->TotalEventSize % 4 == 0)); // ensure 4 byte alignment

            StreamLabel eventDataEnd = reader.Current.Add(eventData->TotalEventSize);

            Debug.Assert(0 <= EventPipeEventHeader.StackBytesSize(eventData) && EventPipeEventHeader.StackBytesSize(eventData) <= eventData->TotalEventSize);

            TraceEventNativeMethods.EVENT_RECORD *ret = null;;
            if (eventData->IsMetadata())
            {
                int totalEventSize = eventData->TotalEventSize;
                int payloadSize    = eventData->PayloadSize;

                // Note that this skip invalidates the eventData pointer, so it is important to pull any fields out we need first.
                reader.Skip(EventPipeEventHeader.HeaderSize);

                var metaData = new EventPipeEventMetaData(reader, payloadSize, _fileFormatVersionNumber, PointerSize, _processId);
                _eventMetadataDictionary.Add(metaData.MetaDataId, metaData);

                _eventParser.AddTemplate(metaData); // if we don't add the templates to this parse, we are going to have unhadled events (see https://github.com/Microsoft/perfview/issues/461)

                int stackBytes = reader.ReadInt32();
                Debug.Assert(stackBytes == 0, "Meta-data events should always have a empty stack");
            }
            else
            {
                if (_eventMetadataDictionary.TryGetValue(eventData->MetaDataId, out var metaData))
                {
                    ret = metaData.GetEventRecordForEventData(eventData);
                }
                else
                {
                    Debug.Assert(false, "Warning can't find metaData for ID " + eventData->MetaDataId.ToString("x"));
                }
            }

            reader.Goto(eventDataEnd);

            return(ret);
        }