// Process DataTable of records for batch / run and allocate ranges of records
        // for each process
        private void MTCalcRecsToProcess(DataTable dt)
        {
            // Calc number of processes needed for all records
            rowCount   = dt.Rows.Count;
            procCount  = rowCount / MTMaxRecsPerProc;
            procCount += (rowCount % MTMaxRecsPerProc == 0) ? 0 : 1;

            // Create array of process status classes
            processStatus = new ProcStat[procCount];

            // For each process status in the array fill in values and presortid ranges
            for (int i = 0; i < processStatus.Length; i++)
            {
                // Create and Number the process
                processStatus[i]         = new ProcStat();
                processStatus[i].ProcNum = i;

                // Get presortIDs for start and end of ranges
                int ndx = MTMaxRecsPerProc * i;
                processStatus[i].RecStart = dt.Rows[ndx]["MPresortID"].ToString();
                ndx += MTMaxRecsPerProc - 1;
                if (ndx > rowCount - 1)
                {
                    ndx = rowCount - 1;
                }
                processStatus[i].RecEnd = dt.Rows[ndx]["MPresortID"].ToString();

                // Initialize the rest of the process status
                processStatus[i].Started    = false;
                processStatus[i].Ended      = false;
                processStatus[i].Error      = false;
                processStatus[i].ReturnCode = 0;
                processStatus[i].Batch      = Batch;
                processStatus[i].Run        = Run;
                processStatus[i].LetterType = Lettertype;
                processStatus[i].RunTime    = string.Empty;
            }

            var tasks = (MTMaxParallelProcs > processStatus.Length) ? processStatus.Length : MTMaxParallelProcs;

            Log.Info(string.Format("MT Individual PDFs: {0} Worker runs, {1} in parallel", procCount, tasks));

            if (WT != null)
            {
                WT.ReportProgress(-2, string.Format("MT Individual PDFs: {0} Worker runs, {1} in parallel",
                                                    procCount, tasks));
            }
        }
Beispiel #2
0
        /// <summary>
        /// Execute several work steps automatically based on fixed list of steps
        /// </summary>
        /// <param name="batch"></param>
        /// <param name="run"></param>
        /// <param name="DSpodfo"></param>
        /// <param name="Ta"></param>
        /// <param name="bs"></param>
        /// <param name="countBS"></param>
        public static void RunAutomated(string batch, string run, PODFODataSet1 DSpodfo,
                                        PODFODataSet1TableAdapters.USP_Select_Batch_Address_To_SortTableAdapter Ta,
                                        BindingSource bs, BindingSource countBS)
        {
            if ((WT != null) && (WT.CancellationPending))
            {
                Log.Error("RunAutomated already canceled");
                return;
            }

            var log = new clsLog();

            log.mstrLogFileLocation = batch + run + ".txt";
            log.WriteToLogfile("Starting RunAutomated");

            log.WriteToLogfile("Starting GenerateIndividualPDFs");
            if (WT != null)
            {
                WT.ReportProgress(-2, String.Format("Make Non WC PDFs"));
            }
            clsGenerateLetters.GenerateIndividualPDFs(batch, run, DSpodfo, Ta, bs);

            log.WriteToLogfile("Starting MakePDFs");
            if (WT != null)
            {
                WT.ReportProgress(-2, String.Format("Make WC PDFs"));
            }
            clsGenerateLettersWC.MakePDFs(batch, run);

            log.WriteToLogfile("Starting MergePDFs");
            if (WT != null)
            {
                WT.ReportProgress(-2, String.Format("Merge"));
            }
            clsMerge.MergePDFs(batch, run);

            log.WriteToLogfile("Starting CreateJobTicket");
            if (WT != null)
            {
                WT.ReportProgress(-2, String.Format("Job Ticket"));
            }
            clsJobTicket.CreateJobTicket(batch, run);

            // log.WriteToLogfile("Starting CreateLetterReportPDF");
            // clsEmail.CreateLetterReportPDF(batch, run, DSpodfo, new PODFODataSet1TableAdapters.USP_SELECT_Letter_CountTableAdapter(), countBS);
            //clsMove.MoveToProduction(batch, run);
        }
Beispiel #3
0
        // "WorkerThread" on it's thread
        private void wt_DoWork(object sender, DoWorkEventArgs e)
        {
            WorkerThread worker = sender as WorkerThread;

            //BGW.ReportProgress(-2, "Reports Application");
            WT.ReportProgress(-2, "Reports Application");
            Application.DoEvents();

            // Start the ReportsApplication on the background worker thread
            var form = new ReportsApplication1.MainForm(batch, run, true, false, Convert.ToInt32(start), Convert.ToInt32(end));
        }
Beispiel #4
0
        public override EntityCollection RetrieveEntities(Model model)
        {
            Entity           ent;
            EntityCollection entities = new EntityCollection();

            DS.SchemaReader.EntitiesDataTable dt = new CodeGenerator.BL.DBReader.DS.SchemaReader.EntitiesDataTable();

            DS.SchemaReaderTableAdapters.EntitiesTableAdapter adp = new CodeGenerator.BL.DBReader.DS.SchemaReaderTableAdapters.EntitiesTableAdapter();
            adp.Connection = new System.Data.SqlClient.SqlConnection(base.ConnectionString);

            adp.Fill(dt, Filter.IncludeTablesAsEntities, Filter.IncludeViewAsEntities, Filter.IncludeForignTables, Filter.SchemasAsCSV());
            base.EntityCount = dt.Rows.Count;
            if (WorkerThread != null && WorkerThread.WorkerReportsProgress)
            {
                WorkerThread.ReportProgress(0);
            }
            int count = 1;

            foreach (DS.SchemaReader.EntitiesRow row in dt.Rows)
            {
                ent             = new Entity();
                ent.Model       = model;
                ent.DBName      = row.TABLE_NAME;
                ent.Schema      = row.TABLE_SCHEMA;
                ent.EntityID    = row.OBJECT_ID.ToString();
                ent.LogicalName = row.TABLE_NAME;

                FillProperties(ent, adp.Connection, null, "schema", ent.Schema, "table", ent.DBName);
                LogicalNameGenerator gen = new LogicalNameGenerator();
                gen.GenerateLogicalName(ent);
                entities.Add(ent);
                if (WorkerThread != null && WorkerThread.WorkerReportsProgress)
                {
                    WorkerThread.ReportProgress((count / base.EntityCount) * 100);
                }
                count++;
            }
            return(entities);
        }
        private void mWorkerThread_DoWork(object sender, DoWorkEventArgs e)
        {
            WorkerThread worker = sender as WorkerThread;

            int duration  = rnd.Next() % 10000 + 10000;
            int steps     = 100;
            int onesleep  = duration / steps;
            int proceeded = 0;

            while (proceeded < duration)
            {
                proceeded += onesleep;
                Thread.Sleep(onesleep);

                worker.ReportProgress(proceeded * 100 / duration);

                if (worker.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
            }
        }
 private void Model_BatchEnd(object sender, EpochEndEventArgs e)
 {
     WorkerThread.ReportProgress(10, e);
 }
        /// <summary>
        /// Make WC PDFs
        /// </summary>
        /// <param name="batch">Batch number</param>
        /// <param name="run">Run number</param>
        /// <param name="intStart">Range Start</param>
        /// <param name="intEnd">Range End</param>
        public static void MakePDFs(string batch, string run, int intStart = 0, int intEnd = 0)
        {
            int       RecordsCount = 0;
            int       RecordsDone  = 0;
            DateTime  lastRPMTime  = DateTime.Now;
            int       RPMCount     = 0;
            Stopwatch totalruntime = new Stopwatch();
            Stopwatch loadtime     = new Stopwatch();

            rpttime = new Stopwatch();
            PDFtime = new Stopwatch();
            int TimeoutErrorRecCount = 0;

            totalruntime.Start();

            Log.SourceBase  = "WCMakePDFs";
            TotalErrorCount = 0;
            ErrorMessages   = new List <string>();


            // Init AppStats info
            stats = new AppStats(DbAccess.GetConnectionString(), "AppStats");
            if (string.IsNullOrEmpty(refID))
            {
                refID = string.Format("{0:yyyyMMddHHmmssff}", DateTime.Now);
            }
            recordID = 0;
            appName  = System.IO.Path.GetFileNameWithoutExtension(Application.ExecutablePath);


            // Record Statistics in AppStats Table
            stats.SetDefaults = true;
            stats.SetField("RefID", refID);
            stats.SetField("AppName", (string.IsNullOrEmpty(appName) ? "ReportsApplication1" : appName));
            stats.SetField("AppSection", "GenerateLettersWC");
            stats.SetField("Batch", batch);
            stats.SetField("Run", run);
            stats.SetField("RangeStart", intStart);
            stats.SetField("RangeEnd", intEnd);
            stats.SetField("TestProd", (UseTestDB) ? "TEST" : "PROD");
            int?ret = stats.InsertRecord();

            if (ret == null)
            {
                string s = string.Format("Error Inserting AppStats record: {0}", stats.Message);
                Log.Error(s);
                TotalErrorCount++;
                ErrorMessages.Add(s);
            }
            else
            {
                recordID = (int)ret;
            }



            if ((WT != null) && (WT.CancellationPending))
            {
                Log.Warn("MakePDFs already canceled");
                TotalErrorCount++;
                stats.SetField("Status", (TotalErrorCount == 0) ? "OK" : "ERRORS");
                stats.SetField("ErrorCount", TotalErrorCount);
                stats.SetField("ErrorMessages", "RunAutomated already canceled");
                stats.SetField("TestProd", (UseTestDB) ? "TEST" : "PROD");
                if (!stats.UpdateRecord())
                {
                    Log.Error(string.Format("Error Updating AppStats record: {0}", stats.Message));
                }
                return;
            }

            if (WT != null)
            {
                WT.ReportProgress(-3, string.Format("R/M: {0:#.##}", 0.0));
                WT.ReportProgress(0, string.Format("Loading Batch / Run rows"));
            }

            Log.Info(string.Format("Start MakePDFs for Batch: {0}  Run: {1} in {2}", batch, run,
                                   (DbAccess.UseTestDB) ? "TEST" : "PROD"));

            try
            {
                // Insure Output Directory exists for the PDFs
                if (!Directory.Exists(strIndiviualPDFPath + "\\" + batch + run))
                {
                    DirectoryInfo di = Directory.CreateDirectory(strIndiviualPDFPath + "\\" + batch + run);
                }

                //string mConnectionString = "Data Source=usasql;Initial Catalog=PODFO;Integrated Security=True;";
                //SqlConnection conn = new SqlConnection(mConnectionString);
                SqlConnection conn = DbAccess.GetConnection();
                SqlCommand    cmd;
                //conn.Open();

                //Get all rows from the table based on the batch and run
                loadtime.Start();
                if (intStart == 0 && intStart == 0)
                {
                    cmd = new SqlCommand("USP_SELECT_WC_LETTERS_FOR_BATCH_RUN");
                }
                else
                {
                    cmd = new SqlCommand("USP_SELECT_WC_LETTERS_FOR_BATCH_RUN_RANGE");
                    cmd.Parameters.AddWithValue("@P_Start_MPresortID", intStart);
                    cmd.Parameters.AddWithValue("@P_End_MPresortID", intEnd);
                }

                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Connection  = conn;
                cmd.Parameters.AddWithValue("@P_PODBatchID", batch);
                cmd.Parameters.AddWithValue("@P_PODRunID", run);
                SqlDataAdapter adapter = new SqlDataAdapter(cmd);

                // Can timeout
                //ds = new DataSet();
                //adapter.Fill(ds);
                DataSet   ds     = null;
                Exception lastex = null;
                bool      rc     = GetDataForWCLettersWithRetry(batch, run, adapter, out ds, out lastex);
                if (!rc || ds == null)
                {
                    string s = string.Format("MakePDFs: Error SQL exceded retries loading letter data: {0}", lastex.Message);
                    Log.Error(s);
                    // Show Error
                    if (WT != null)
                    {
                        WT.ReportProgress(-1, s);
                    }
                    clsEmail.EmailMessage(string.Format("Error from PODFO.MakePDFs {0}", (UseTestDB) ? "TESTING" : ""), s);

                    TotalErrorCount++;
                    TimeoutErrorRecCount++;
                    stats.SetField("Status", (TotalErrorCount == 0) ? "OK" : "ERRORS");
                    stats.SetField("ErrorCount", TotalErrorCount);
                    stats.SetField("ErrorMessages", s);
                    stats.SetField("TestProd", (UseTestDB) ? "TEST" : "PROD");
                    stats.SetField("AppCount1", TimeoutErrorRecCount);
                    if (!stats.UpdateRecord())
                    {
                        Log.Error(string.Format("Error Updating AppStats record: {0}", stats.Message));
                    }
                    return;
                }

                RecordsCount = ds.Tables[0].Rows.Count;
                loadtime.Stop();

                lastRPMTime       = DateTime.Now;
                RPMCount          = 0;
                fileNotFoundCount = 0;

                if (WT != null)
                {
                    WT.ReportProgress(0, string.Format("Recs Done {0} of {1}", RecordsDone, RecordsCount));
                }

                rpttime.Start();
                foreach (DataRow dr in ds.Tables[0].Rows)
                {
                    //create the report
                    CreateWCReport(dr);

                    RecordsDone++;
                    RPMCount++;

                    if (WT != null)
                    {
                        // Check if cancel pending, set canceled flag
                        if (WT.CancellationPending)
                        {
                            Log.Warn("MakePDFs: Canceled by Background Worker Request");
                            TotalErrorCount++;
                            ErrorMessages.Add("MakePDFs: Canceled by Background Worker Request");
                            break;
                        }

                        // Report Background worker thread status
                        int pcrecsdone = (RecordsDone * 100) / (RecordsCount);
                        if (RecordsDone % ReportProgressCount == 0)
                        {
                            // Report Progress % and count of recs processed
                            WT.ReportProgress(pcrecsdone, string.Format("Recs Done {0} of {1}", RecordsDone, RecordsCount));

                            // Report records per minute
                            var rpm = RPMCount / (DateTime.Now - lastRPMTime).TotalMinutes;
                            WT.ReportProgress(-3, string.Format("R/M: {0:#.##}", rpm));
                            lastRPMTime = DateTime.Now;
                            RPMCount    = 0;
                        }
                    }
                }
                rpttime.Stop();
            }

            catch (Exception ex)
            {
                var log = new clsLog();
                log.mstrLogFileLocation = batch + run + ".txt";
                log.WriteToLogfile("clsGenerateLettersWC.MakePDFs " + ex.Message);
                string s = string.Format("Error: clsGenerateLettersWC.MakePDFs Batch: {0}, Run: {1} : {2}", batch, run, ex.Message);
                Log.Error(s);
                ErrorMessages.Add(s);
                TotalErrorCount++;

                clsEmail.EmailMessage(string.Format("Error from PODFO {0}", (UseTestDB) ? "TESTING" : ""),
                                      "clsGenerateLettersWC.MakePDFs " + ex.Message);
            }

            finally
            {
                // Show 100% done
                if (WT != null)
                {
                    WT.ReportProgress(100, string.Format("Recs Done {0} of {1}", RecordsDone, RecordsCount));
                }

                string s2 = string.Format("MakePDFs: Record count: {0}, Files not found count: {1}",
                                          RecordsCount, fileNotFoundCount);
                Log.Info(s2);

                if (fileNotFoundCount > 0)
                {
                    string msg = string.Format("Error: clsGenerateLettersWC.MakePDFs: There were {0} WCZip files not found",
                                               fileNotFoundCount);
                    Log.Error(msg);
                    clsEmail.EmailMessage(string.Format("Error from PODFO {0}", (UseTestDB) ? "TESTING" : ""), msg);
                }

                // Count PDF files created
                var TotalPDFCount = Directory.EnumerateFiles(strIndiviualPDFPath + batch + run, "*.PDF").Where(x => x.ToUpper().Contains(".PDF")).Count();
                Log.Info(string.Format("MakePDFs: Total PDFs in BatchRun Folder: {0}", TotalPDFCount));
                totalruntime.Stop();


                // Limit Error messages string for DB
                string errorMessages = string.Empty;
                if (ErrorMessages.Count > 0)
                {
                    errorMessages = ErrorMessages.Aggregate((a, b) => a + ", " + b);
                    if (errorMessages.Length > 1023)
                    {
                        errorMessages = errorMessages.Substring(0, 1023);
                    }
                }

                string appnotes = string.Format("WC Recs Done {0} of {1}, files not found: {2}, PDF Files in folder: {3}",
                                                RecordsDone, RecordsCount, fileNotFoundCount, TotalPDFCount);

                // Record Statistics in AppStats Table
                Process procObj = Process.GetCurrentProcess();
                stats.SetField("Status", (TotalErrorCount == 0) ? "OK" : "ERRORS");
                stats.SetField("ErrorCount", TotalErrorCount);
                stats.SetField("ErrorMessages", errorMessages);
                stats.SetField("TestProd", (UseTestDB) ? "TEST" : "PROD");
                stats.SetField("AppNotes", appnotes);
                stats.SetField("MaxMemUsedMB", (int)(procObj.PeakVirtualMemorySize64 / 1048576L));
                stats.SetField("ExpectedCountOut", RecordsCount);
                stats.SetField("InputCount1", RecordsCount);
                stats.SetField("OutputCount1", TotalPDFCount);
                stats.SetField("OutputCount2", RecordsDone);
                stats.SetField("InputTimeSecs1", loadtime.Elapsed.TotalSeconds);
                stats.SetField("ProcessTimeSecs1", rpttime.Elapsed.TotalSeconds);
                stats.SetField("OutputTimeSecs1", PDFtime.Elapsed.TotalSeconds);
                stats.SetField("TotalRunTimeSecs", totalruntime.Elapsed.TotalSeconds);
                stats.SetField("AppCount2", fileNotFoundCount);
                bool rcstats = stats.UpdateRecord();
                if (!rcstats)
                {
                    Log.Error(string.Format("Error Updating AppStats record: {0}", stats.Message));
                }
                Log.Info(string.Format("End MakePDFs for Batch: {0}, Run: {1}", batch, run));
            }
        }
Beispiel #8
0
        /// <summary>
        /// Merge the individual PDFs
        /// </summary>
        /// <param name="batch">Batch number for this process</param>
        /// <param name="run">Run number for this process</param>
        public static void MergePDFs(string batch, string run)
        {
            int intcount    = 0;
            int intEnd      = 0;
            int intStart    = 1;
            int introwcount = 0;
            int RecsDone    = 0;
            //DateTime lastRPMTime = new DateTime();
            int RPMCount            = 0;
            int filesCountThisMerge = 0;

            int intDBpagecount  = 0;
            int intPDFpagecount = 0;

            totalruntime = new Stopwatch();
            totalruntime.Start();
            int fileNotFoundCount = 0;
            int RecordsOuput      = 0;

            loadtime      = new Stopwatch();
            mergetime     = new Stopwatch();
            PDFtime       = new Stopwatch();
            ErrorMessages = new List <string>();


            // Init AppStats info
            stats = new AppStats(DbAccess.GetConnectionString(), "AppStats");
            if (string.IsNullOrEmpty(refID))
            {
                refID = string.Format("{0:yyyyMMddHHmmssff}", DateTime.Now);
            }
            recordID = 0;
            appName  = System.IO.Path.GetFileNameWithoutExtension(Application.ExecutablePath);


            // Record Statistics in AppStats Table
            stats.SetDefaults = true;
            stats.SetField("RefID", refID);
            stats.SetField("AppName", (string.IsNullOrEmpty(appName) ? "ReportsApplication1" : appName));
            stats.SetField("AppSection", "MergePDFs");
            stats.SetField("Batch", batch);
            stats.SetField("Run", run);
            stats.SetField("TestProd", (UseTestDB) ? "TEST" : "PROD");
            stats.SetField("AppCount3", FilesPerMerge);
            int?ret = stats.InsertRecord();

            if (ret == null)
            {
                string s = string.Format("Error Inserting AppStats record: {0}", stats.Message);
                Log.Error(s);
                TotalErrorCount++;
                ErrorMessages.Add(s);
            }
            else
            {
                recordID = (int)ret;
            }



            if ((WT != null) && (WT.CancellationPending))
            {
                Log.Error("MergePDFs already canceled");
                TotalErrorCount++;
                stats.SetField("Status", (TotalErrorCount == 0) ? "OK" : "ERRORS");
                stats.SetField("ErrorCount", TotalErrorCount);
                stats.SetField("ErrorMessages", "RunAutomated already canceled");
                stats.SetField("TestProd", (UseTestDB) ? "TEST" : "PROD");
                if (!stats.UpdateRecord())
                {
                    Log.Error(string.Format("Error Updating AppStats record: {0}", stats.Message));
                }
                return;
            }

            if (WT != null)
            {
                WT.ReportProgress(-2, String.Format("Merge PDFs"));
                WT.ReportProgress(-3, string.Format("R/M: {0:#.##}", 0.0));
            }


            try
            {
                Log.Info(string.Format("MergePDFs starting for Batch: {0}, Run: {1}, FilesPerMerge: {2}",
                                       batch, run, FilesPerMerge));

                var log = new clsLog();
                log.mstrLogFileLocation = batch + run + ".txt";

                loadtime.Start();
                var            DA      = new clsGetBatchSort();
                SqlDataAdapter adapter = new SqlDataAdapter(DA.dsBatch_Sort(batch, run));
                DataSet        ds      = new DataSet();
                adapter.Fill(ds);

                introwcount = ds.Tables[0].Rows.Count;
                loadtime.Stop();


                //int LetterTypeID = 0;
                if (WT != null)
                {
                    WT.ReportProgress(0, string.Format("Collecting page count"));
                }

                foreach (DataRow dr in ds.Tables[0].Rows)
                {
                    intDBpagecount += Convert.ToInt32(dr["PageCount"]);
                }


                ceTe.DynamicPDF.Document.AddLicense(ceTeLicense);
                //Dim intRecordCount As Integer = 1
                //Dim rootValue As String
                string mergePath = strMergeFilePath + "\\" + batch + run;

                if (!Directory.Exists(mergePath))
                {
                    DirectoryInfo di = Directory.CreateDirectory(mergePath);
                }



                string[] fileEntries = Directory.GetFiles(strFilePath + "\\" + batch + run);
                string   fmt         = "00000000";
                //string filename = Path.Combine("C:\\PDF\\", "report" + PreSortID.ToString(fmt) + ".pdf");
                //string filename = Path.Combine(mstrFilePath + "\\" + batch + run + "\\" + PreSortID.ToString(fmt) + ".pdf");
                string filename;

                ceTe.DynamicPDF.Merger.MergeDocument myTempDoc = new ceTe.DynamicPDF.Merger.MergeDocument();
                string missingfiles = "";

                mergetime.Start();
                if (introwcount != 0)                      //make sure files where imported
                {
                    if (fileEntries.Length == introwcount) //make sure file count matches pdf count
                    {
                        for (int i = 1; i < fileEntries.Length + 1; i++)
                        {
                            filename = strFilePath + "\\" + batch + run + "\\" + i.ToString(fmt) + ".PDF";

                            if (fileEntries[i - 1].ToString().Equals(filename))
                            {
                                intcount += 1;
                                intEnd   += 1;

                                // Merge file
                                myTempDoc.Append(filename);
                                filesCountThisMerge++;

                                //shut pdf every "n" files to avoid errors
                                //if ((myTempDoc.Pages.Count >= PagesPerMerge))
                                if (filesCountThisMerge >= FilesPerMerge)
                                {
                                    PDFtime.Start();
                                    log.WriteToLogfile("about to combine myTempDoc " + myTempDoc.Pages.Count + " Pages");
                                    myTempDoc.CompressionLevel = 0;
                                    myTempDoc.PdfVersion       = ceTe.DynamicPDF.PdfVersion.v1_3;
                                    intPDFpagecount           += myTempDoc.Pages.Count;
                                    //creates pdf
                                    log.WriteToLogfile("myTempDoc.Draw(" + mergePath + "\\PODFO " + batch + run + " " + intStart + "-" + intEnd + ".Pdf)");
                                    myTempDoc.Draw(mergePath + "\\PODFO " + batch + run + " " + intStart + "-" + intEnd + ".Pdf");
                                    myTempDoc = null;
                                    GC.Collect();
                                    intStart  = intEnd + 1;
                                    intcount  = 0;
                                    myTempDoc = new ceTe.DynamicPDF.Merger.MergeDocument();

                                    log.WriteToLogfile("Finished Drawing");
                                    Log.Info("myTempDoc.Draw(" + mergePath + "\\PODFO " + batch + run + " " + intStart + "-" + intEnd + ".Pdf)");
                                    RecordsOuput++;
                                    PDFtime.Stop();
                                    filesCountThisMerge = 0;
                                }
                            }
                            else
                            {
                                missingfiles = missingfiles + ", " + i;
                                log.WriteToLogfile("missing file: " + i.ToString());
                                // MessageBox.Show("missing file: " + i.ToString());
                                fileNotFoundCount++;
                            }

                            RecsDone++;
                            RPMCount++;

                            // Report Background worker thread status
                            if (WT != null)
                            {
                                // Check if cancel pending, set canceled flag
                                if (WT.CancellationPending)
                                {
                                    BGWCanceled = true;
                                    break;
                                }

                                // Report Progress % and count of recs processed
                                int pcrecsdone = (RecsDone * 100) / (introwcount);
                                if (intcount % 20 == 0)
                                {
                                    WT.ReportProgress(pcrecsdone, string.Format("Recs Done {0} of {1}", RecsDone, introwcount));

                                    // Report records per minute
                                    //var rpm = RPMCount / (DateTime.Now - lastRPMTime).TotalMinutes;
                                    //BGW.ReportProgress(-3, string.Format("R/M: {0:#.##}", rpm));
                                    //lastRPMTime = DateTime.Now;
                                    //RPMCount = 0;
                                }
                            }
                        }

                        // If merge in progress, write out last merge file
                        //if ((myTempDoc.Pages.Count != PagesPerMerge))
                        if (filesCountThisMerge != FilesPerMerge)
                        {
                            PDFtime.Start();
                            log.WriteToLogfile("about to combine myTempDoc " + myTempDoc.Pages.Count + " Pages");
                            log.WriteToLogfile("myTempDoc.Draw(" + mergePath + "\\PODFO " + batch + run + " " + intStart + "-" + intEnd + ".Pdf)");
                            myTempDoc.CompressionLevel = 0;
                            myTempDoc.PdfVersion       = ceTe.DynamicPDF.PdfVersion.v1_3;
                            intPDFpagecount           += myTempDoc.Pages.Count;
                            //creates pdf
                            myTempDoc.Draw(mergePath + "\\PODFO " + batch + run + " " + intStart + "-" + intEnd + ".Pdf");
                            myTempDoc = null;
                            GC.Collect();
                            log.WriteToLogfile("Finished Drawing");
                            Log.Info("myTempDoc.Draw(" + mergePath + "\\PODFO " + batch + run + " " + intStart + "-" + intEnd + ".Pdf)");
                            RecordsOuput++;
                            PDFtime.Stop();
                            filesCountThisMerge = 0;
                        }

                        if (WT != null)
                        {
                            WT.ReportProgress(100, string.Format("Recs Done {0} of {1}", intEnd, introwcount));
                        }
                    }
                    else
                    {
                        //email
                        string s = string.Format("clsMerge.MergePDFs: Missing file fileEntries.Length = {0} and introwcount = {1}",
                                                 fileEntries.Length, introwcount);
                        Log.Info(s);
                        log.WriteToLogfile("Missing file fileEntries.Length = " + fileEntries.Length + " and introwcount = " + introwcount);
                        // MessageBox.Show("Missing file fileEntries.Length = " + fileEntries.Length + " and introwcount = " + introwcount);

                        if (WT != null)
                        {
                            WT.ReportProgress(100, string.Format("Record counts don't match: Files: {0},  DB Rows: {1}",
                                                                 fileEntries.Length, introwcount));
                        }
                    }
                }
                else
                {
                    Log.Info("MergePDFs: No files to process");
                }
            }
            catch (Exception ex)
            {
                TotalErrorCount++;
                var log = new clsLog();
                log.mstrLogFileLocation = batch + run + ".txt";
                log.WriteToLogfile("clsMerge.MergePDFs " + ex.Message + " Stack trace " + ex.StackTrace + " Inner ex " + ex.InnerException);
                clsEmail.EmailMessage(string.Format("PODFO error {0}", (UseTestDB) ? " TESTING" : ""),
                                      "Error merging pdfs. Message: " + ex.Message + " The pdf count was " + intEnd);
                //  MessageBox.Show("Error merging pdfs. Message: " + ex.Message + " The pdf count was " + intEnd);

                string s = string.Format("clsMerge.MergePDFs Exception: {0}", ex.Message);
                Log.Error(s);
                ErrorMessages.Add(s);
                s = string.Format("clsMerge.MergePDFs Exception Inner: {0}", ex.InnerException);
                Log.Error(s);
                s = string.Format("clsMerge.MergePDFs Exception Stack: {0}", ex.StackTrace);
                Log.Error(s);
            }
            finally
            {
                totalruntime.Stop();
                mergetime.Stop();
                string s = string.Format("clsMerge.MergePDFs: Rowount: {0}, DBPageCount: {1}, Time: {2}",
                                         introwcount, intDBpagecount, totalruntime.Elapsed.ToString(@"hh\:mm\:ss\.f"));
                Log.Info(s);

                // Limit Error messages string for DB
                string errorMessages = string.Empty;
                if (ErrorMessages.Count > 0)
                {
                    errorMessages = ErrorMessages.Aggregate((a, b) => a + ", " + b);
                    if (errorMessages.Length > 1023)
                    {
                        errorMessages = errorMessages.Substring(0, 1023);
                    }
                }

                // Record Statistics in AppStats Table
                Process procObj = Process.GetCurrentProcess();
                stats.SetField("Status", (TotalErrorCount == 0) ? "OK" : "ERRORS");
                stats.SetField("ErrorCount", TotalErrorCount);
                stats.SetField("ErrorMessages", errorMessages);
                stats.SetField("TestProd", (UseTestDB) ? "TEST" : "PROD");
                stats.SetField("AppNotes", s);
                stats.SetField("MaxMemUsedMB", (int)(procObj.PeakVirtualMemorySize64 / 1048576L));
                //stats.SetField("ExpectedCountOut", RecordsCount);
                stats.SetField("InputCount1", RecsDone);
                stats.SetField("OutputCount1", RecordsOuput);
                stats.SetField("OutputCount2", intDBpagecount);
                stats.SetField("InputTimeSecs1", loadtime.Elapsed.TotalSeconds);
                stats.SetField("ProcessTimeSecs1", mergetime.Elapsed.TotalSeconds);
                stats.SetField("OutputTimeSecs1", PDFtime.Elapsed.TotalSeconds);
                stats.SetField("TotalRunTimeSecs", totalruntime.Elapsed.TotalSeconds);
                stats.SetField("AppCount2", fileNotFoundCount);
                bool rcstats = stats.UpdateRecord();
                if (!rcstats)
                {
                    Log.Error(string.Format("Error Updating AppStats record: {0}", stats.Message));
                }
            }
        }