/// <summary> /// Starts a task that is responsible for deserializing all non-path events as fed to it through the specified queue /// </summary> /// <param name="nonPathEventsToDeserialize">The queue where non-path events (as file positions) to deserialize will be fed</param> /// <returns>A task that will finish when the queue that it consumes from is both marked completed and empty</returns> private Task CreateNonPathEventConsumerTask(BlockingCollection <long> nonPathEventsToDeserialize) { return(Task.Run(() => { using (FileStream fileStream = File.Open(m_logFilename, FileMode.Open, FileAccess.Read, FileShare.Read)) { ParallelEventReader parallelEventReader = new ParallelEventReader(this, fileStream); while (!nonPathEventsToDeserialize.IsCompleted) { // Get next event file position long positionToDeserialize; try { positionToDeserialize = nonPathEventsToDeserialize.Take(); } catch (InvalidOperationException) { // This exception is thrown when CompleteAdding is called while we are blocked on the call to Take // If we see this exception, we know we are done processing events and the task can exit return; } // Seek to the start of the next event to deserialize fileStream.Seek(positionToDeserialize, SeekOrigin.Begin); EventHeader header = EventHeader.ReadFrom(parallelEventReader); // Ensure that event id is NOT an AddPath event Contract.Assert((BinaryLogger.LogSupportEventId)header.EventId != BinaryLogger.LogSupportEventId.AddPath); var startOfNextEvent = fileStream.Position + header.EventPayloadSize; // Handle the internal events if (header.EventId < (uint)BinaryLogger.LogSupportEventId.Max) { switch ((BinaryLogger.LogSupportEventId)header.EventId) { case BinaryLogger.LogSupportEventId.StartTime: ReadStartTimeEvent(parallelEventReader); break; case BinaryLogger.LogSupportEventId.AddStringId: ReadStringIdEvent(parallelEventReader); break; } Contract.Assert(fileStream.Position == startOfNextEvent); continue; } else { header.EventId -= (uint)BinaryLogger.LogSupportEventId.Max; } EventHandler handler; if ((m_handlers.Length > header.EventId) && ((handler = m_handlers[header.EventId]) != null)) { handler(header.EventId, header.WorkerId, header.Timestamp, parallelEventReader); Contract.Assert(fileStream.Position <= startOfNextEvent, "Event handler read beyond the event payload"); } } } })); }