public override void Initialize()
        {
            using (SqlConnection conn = new SqlConnection())
            {
                conn.ConnectionString = ConnectionInfo.ConnectionString;
                conn.Open();

                string traceSql = null;
                try
                {
                    traceSql = System.IO.File.ReadAllText(Source);

                    // Push Down EventFilters
                    string filters = "";
                    filters += Environment.NewLine + Filter.ApplicationFilter.PushDown();
                    filters += Environment.NewLine + Filter.DatabaseFilter.PushDown();
                    filters += Environment.NewLine + Filter.HostFilter.PushDown();
                    filters += Environment.NewLine + Filter.LoginFilter.PushDown();

                    tracePath = utils.GetSqlDefaultLogPath(conn);
                    traceSql  = String.Format(traceSql, TraceSizeMB, TraceRolloverCount, Path.Combine(tracePath, "sqlworkload"), filters);
                }
                catch (Exception e)
                {
                    throw new ArgumentException("Cannot open the source script to start the sql trace", e);
                }

                int id = utils.GetTraceId(conn, Path.Combine(tracePath, "sqlworkload"));
                if (id > 0)
                {
                    StopTrace(conn, id);
                }

                SqlCommand cmd = conn.CreateCommand();
                cmd.CommandText = traceSql;
                traceId         = (int)cmd.ExecuteScalar();

                // Initialize the source of execution related events
                if (StreamSource == StreamSourceEnum.StreamFromFile)
                {
                    Task.Factory.StartNew(() => ReadEventsFromFile());
                }
                else if (StreamSource == StreamSourceEnum.StreamFromTDS)
                {
                    Task.Factory.StartNew(() => ReadEventsFromTDS());
                }


                // Initialize the source of performance counters events
                Task.Factory.StartNew(() => ReadPerfCountersEvents());

                // Initialize the source of wait stats events
                Task.Factory.StartNew(() => ReadWaitStatsEvents());
            }
        }
        private ReadIteration InitializeReadIteration(SqlConnection conn, ReadIteration previous)
        {
            string sqlPath = @"
                SELECT path
                FROM sys.traces
                WHERE id = @traceId
            ";

            string sqlPathLocaldb = @"
                IF OBJECT_ID('tempdb.dbo.trace_reader_queue') IS NOT NULL
                BEGIN
                    SELECT TOP(1) path
                    FROM tempdb.dbo.trace_reader_queue
                    ORDER BY ts DESC
                END
                ELSE
                BEGIN
                    SELECT '' AS path
                END
            ";

            ReadIteration currentIteration = null;

            using (SqlCommand cmdPath = conn.CreateCommand())
            {
                if (conn.DataSource.StartsWith("(localdb)", StringComparison.InvariantCultureIgnoreCase))
                {
                    cmdPath.CommandText = sqlPathLocaldb;
                }
                else
                {
                    cmdPath.CommandText = sqlPath;

                    // Get trace id
                    if (traceId == -1)
                    {
                        string tracePath = utils.GetSqlDefaultLogPath(conn);
                        traceId = utils.GetTraceId(conn, Path.Combine(tracePath, "sqlworkload"));
                        if (traceId == -1)
                        {
                            throw new InvalidOperationException("The SqlWorkload capture trace is not running.");
                        }
                    }
                    var paramTraceId = cmdPath.Parameters.Add("@traceId", System.Data.SqlDbType.Int);
                    paramTraceId.Value = traceId;
                }


                try
                {
                    logger.Debug("Initializing read iteration");

                    using (SqlDataReader reader = cmdPath.ExecuteReader())
                    {
                        // should return only one row
                        if (reader.Read())
                        {
                            currentIteration = new ReadIteration()
                            {
                                StartFileName = reader.GetString(0),
                                Files         = 1
                            };
                            currentIteration.EndFileName = currentIteration.StartFileName;
                            if (previous != null)
                            {
                                //if we have a previous iteration, keep reading from that file first
                                currentIteration.StartFileName = previous.EndFileName;
                                // if the file has changed from the previous iteration
                                // read the default number of files ( = 0 )
                                if (currentIteration.StartFileName != currentIteration.EndFileName)
                                {
                                    currentIteration.Files = 0;
                                }

                                // we will use the previous event sequence as the boundary to where
                                // we need to start reading events again
                                currentIteration.StartSequence = previous.EndSequence;
                                currentIteration.EndSequence   = previous.EndSequence;

                                // trace files do not have an offset like xe files but
                                // the offset can be used to go back and read events
                                // from the previous sequence minus a safety offset
                                currentIteration.StartOffset = previous.EndSequence - ReadIteration.TRACE_DEFAULT_OFFSET;

                                // if reading from localdb we don't need to wait for more data
                                if (conn.DataSource.StartsWith("(localdb)", StringComparison.InvariantCultureIgnoreCase))
                                {
                                    if (
                                        (currentIteration.StartFileName == previous.StartFileName) &&
                                        (currentIteration.StartSequence == previous.StartSequence)
                                        )
                                    {
                                        return(null);
                                    }
                                }
                            }

                            logger.Debug($"currentIteration.StartFileName: {currentIteration.StartFileName}");
                            logger.Debug($"currentIteration.MinOffset    : {currentIteration.MinOffset}");
                            logger.Debug($"currentIteration.EndFileName  : {currentIteration.EndFileName}");
                            logger.Debug($"currentIteration.StartOffset  : {currentIteration.StartOffset}");
                            logger.Debug($"currentIteration.StartSequence: {currentIteration.StartSequence}");
                        }
                    }
                }
                catch (Exception e)
                {
                    logger.Error(e.StackTrace);
                    throw;
                }
            }
            return(currentIteration);
        }