private void OpenEtwEventCacheFile(object context)
        {
            ReadEventsFromFileParam param = (ReadEventsFromFileParam)context;

            param.FileNotFound = false;
            try
            {
                FileStream fileStream = FabricFile.Open(param.FileName, FileMode.Open, FileAccess.Read);
#if !DotNetCoreClr
                Helpers.SetIoPriorityHint(fileStream.SafeFileHandle, Kernel32Types.PRIORITY_HINT.IoPriorityHintVeryLow);
#endif
                param.StreamReader = new StreamReader(fileStream);
            }
            catch (FileNotFoundException e)
            {
                // The file was not found, most likely because it was deleted by
                // the old logs deletion routine.
                this.TraceSource.WriteWarning(
                    this.LogSourceId,
                    "Exception occurred while trying to open buffered event file {0} for read. The file may have been deleted. Exception information: {1}",
                    param.FileName,
                    e);
                param.FileNotFound = true;
            }
        }
        private void ProcessEventsFromFile(string fileName)
        {
            this.TraceSource.WriteInfo(
                this.LogSourceId,
                "Processing ETW events from file {0}.",
                fileName);

            // Open the file
            ReadEventsFromFileParam readEventsParam = new ReadEventsFromFileParam();

            readEventsParam.StreamReader = null;
            readEventsParam.FileName     = fileName;
            try
            {
                Utility.PerformIOWithRetries(
                    this.OpenEtwEventCacheFile,
                    readEventsParam);
            }
            catch (Exception e)
            {
                this.TraceSource.WriteExceptionAsError(
                    this.LogSourceId,
                    e,
                    "Failed to open file {0} for read.",
                    fileName);
                return;
            }

            if (readEventsParam.FileNotFound)
            {
                Debug.Assert(null == readEventsParam.StreamReader, "StreamReader should remain unset if file is not found.");
                return;
            }

            // Read and process events from the file
            try
            {
                // Check the DCA version to make sure we can parse this file
                int version;
                if (false == this.CanParseFile(readEventsParam.StreamReader, fileName, out version))
                {
                    return;
                }

                // Upload the ETW events that we just retrieved
                this.TraceSource.WriteInfo(
                    this.LogSourceId,
                    "Starting delivery of ETW events from file {0} ....",
                    fileName);

                LineParam lineParam = new LineParam();
                lineParam.Reader = readEventsParam.StreamReader;
                for (;;)
                {
                    // Read an event from the file
                    try
                    {
                        ReadLineFromFile(lineParam);
                    }
                    catch (Exception e)
                    {
                        this.TraceSource.WriteExceptionAsError(
                            this.LogSourceId,
                            e,
                            "Failed to read event from file {0}.",
                            fileName);
                        break;
                    }

                    if (null == lineParam.Line)
                    {
                        // End of file reached
                        break;
                    }

                    DecodedEtwEvent etwEventInfo      = new DecodedEtwEvent();
                    string          nodeUniqueEventId = null;
                    if (false == this.ParseEventInfo(fileName, version, lineParam.Line, ref etwEventInfo, ref nodeUniqueEventId))
                    {
                        // Couldn't parse this event, so skip it and continue with the
                        // remaining events.
                        continue;
                    }

                    // Deliver the event to the consumer
                    this.eventSink.OnEtwEventAvailable(etwEventInfo, nodeUniqueEventId);
                    this.perfHelper.EventDeliveredToConsumer();

                    // If the consumer has asked for the event delivery period to
                    // be aborted, then do so immediately.
                    if (this.eventDeliveryPeriodAborted)
                    {
                        this.TraceSource.WriteInfo(
                            this.LogSourceId,
                            "The event delivery pass is being aborted. Therefore, no more events will be read from file {0}.",
                            fileName);
                        break;
                    }

                    // If we are in the process of stopping, then don't process
                    // any more events
                    if (this.Stopping)
                    {
                        this.TraceSource.WriteInfo(
                            this.LogSourceId,
                            "The consumer is being stopped. Therefore, no more events will be read from file {0}.",
                            fileName);
                        break;
                    }
                }

                this.TraceSource.WriteInfo(
                    this.LogSourceId,
                    "Finished delivery of ETW events from file {0}.",
                    fileName);
            }
            finally
            {
                readEventsParam.StreamReader.Dispose();
            }
        }