0

I have a windows service that is supposed to check for a record, email a report for that record, delete the record and then repeat for the table. It checks for the record, emails a report for the first record then shuts off. Any ideas??

Service code:

namespace ReportSender
{

    public partial class EmailReportService : ServiceBase
    {
        private EmailReportApp _app = new EmailReportApp();
        public Timer serviceTimer = new Timer();


        public EmailReportService()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {

            //Set interval (from App Settings) and enable timer 
            serviceTimer.Elapsed += new ElapsedEventHandler(ServiceTimer_OnElapsed);
            //Use Conversion utility to determine next start date/time based on properties, use DateTime.Subtract() to find milliseconds difference between Now and the next start time 
            //serviceTimer.Interval = Date.AddInterval(Properties.Settings.Default.IntervalType, Properties.Settings.Default.Interval).Subtract(DateTime.Now).TotalMilliseconds;
            serviceTimer.Interval = 600000;
            serviceTimer.Enabled = true;

        }

        protected override void OnStop()
        {

            //Stop and disable timer 
            serviceTimer.Enabled = false;
        }

        private void ServiceTimer_OnElapsed(object source, ElapsedEventArgs e)
        {
            try
            {
                //Stop the timer to prevent overlapping runs 
                serviceTimer.Stop();
                //Start service 
                //Run your app.Start() code 
                _app = new EmailReportApp();

                _app.Start();




            }
            catch (Exception ex)
            {

            }
            finally
            {
                //Re-start the timer 
                serviceTimer.Start();
            }
        }

    }
}

Code the service is supposed to execute:

namespace ReportSender
{
    class EmailReportApp
    {

        // Private fields
        private Thread _thread;
        private EventLog _log;



        private void Execute()
        {

            try
            {

                    // Check for a new record
                    DataClasses1DataContext dc = new DataClasses1DataContext();

                    foreach (var item in dc.reportsSent1s)
                    {
                        string matchedCaseNumber = item.CaseNumberKey;
                        (new MyReportRenderer()).RenderTest(matchedCaseNumber);

                        dc.reportsSent1s.DeleteOnSubmit(item);
                        dc.SubmitChanges();
                    }



            }
            catch (ThreadAbortException ex)
            {
                _log.WriteEntry(ex.StackTrace.ToString());

                }
            }


        public void Start()
        {
            if (!EventLog.SourceExists("EventLoggerSource"))
                EventLog.CreateEventSource("EventLoggerSource", "Event Logger");
            _log = new EventLog("EventLoggerSource");
            _log.Source = "EventLoggerSource";

            _thread = new Thread(new ThreadStart(Execute));
            _thread.Start();
        }

        public void Stop()
        {
            if (_thread != null)
            {
                _thread.Abort();
                _thread.Join();
            }
        }

    }


    public class MyReportRenderer
    {

        private rs2005.ReportingService2005 rs;
        private rs2005Execution.ReportExecutionService rsExec;



        public void RenderTest(String matchedCaseNumber)
        {
            string HistoryID = null;
            string deviceInfo = null;
            string encoding = String.Empty;
            string mimeType = String.Empty;
            string extension = String.Empty;
            rs2005Execution.Warning[] warnings = null;
            string[] streamIDs = null;

            rs = new rs2005.ReportingService2005();
            rsExec = new rs2005Execution.ReportExecutionService();
            rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
            rsExec.Credentials = System.Net.CredentialCache.DefaultCredentials;
            rs.Url = "http://***.**.***.**/ReportServer_DEVELOPMENT/ReportService2005.asmx";
            rsExec.Url = "http://***.**.***.**/ReportServer_DEVELOPMENT/ReportExecution2005.asmx";


            try
            {
                // Load the selected report.
                rsExec.LoadReport("/LawDept/LawDeptTIC", HistoryID);

                // Set the parameters for the report needed.

                rs2005Execution.ParameterValue[] parameters = new rs2005Execution.ParameterValue[1];
                parameters[0] = new rs2005Execution.ParameterValue();
                parameters[0].Name = "CaseNumberKey";
                parameters[0].Value = matchedCaseNumber;

                rsExec.SetExecutionParameters(parameters, "en-us");

                // get pdf of report 
                Byte[] results = rsExec.Render("PDF", deviceInfo,
                out extension, out encoding,
                out mimeType, out warnings, out streamIDs);

                //pass paramaters for email
                DataClasses1DataContext db = new DataClasses1DataContext();



                var matchedBRT = (from c in db.GetTable<vw_ProductClientInfo>()
                                  where c.CaseNumberKey == matchedCaseNumber
                                  select c.BRTNumber).SingleOrDefault();

                var matchedAdd = (from c in db.GetTable<vw_ProductClientInfo>()
                                  where c.CaseNumberKey == matchedCaseNumber
                                  select c.Premises).SingleOrDefault();



                //send email with attachment
                MailMessage message = new MailMessage("234@acmetaxabstracts.com", "georr@gmail.com", "Report for BRT # " + matchedAdd, "Attached if the Tax Information Certificate for the aboved captioned BRT Number");
                MailAddress copy = new MailAddress("a123s@gmail.com");
                message.CC.Add(copy);
                SmtpClient emailClient = new SmtpClient("***.**.***.**");
                message.Attachments.Add(new Attachment(new MemoryStream(results), String.Format("{0}" + matchedBRT + ".pdf", "BRT")));
                emailClient.Send(message);


            }

            catch (Exception ex)
            {


            }
        }
    }
}
korrowan
  • 563
  • 2
  • 15
  • 37
  • i think the finally-block in your servicetimer may not be getting executed due to some kind of interruption from your email thread. it happens in java sometimes (see http://stackoverflow.com/questions/464098/does-a-finally-block-always-run). – a_schimpf May 31 '13 at 14:00
  • @a_schimpf I did run this in a different manner using a loop without the finally block and it still did the same thing. After it renders the report and emails it it shuts off before dc.reportsSent1s.DeleteOnSubmit(item); dc.SubmitChanges(); is executed. – korrowan May 31 '13 at 14:05
  • Hey Korrowan looks like still having issues, did you ever output anything in your try catch from the email portion of the code to make sure nothing is going on there? – Bearcat9425 May 31 '13 at 14:08
  • @Bearcat9425 no matter where I try to catch an error nothing comes up in my logs. – korrowan May 31 '13 at 15:13

1 Answers1

2

The 'ServiceBase' is losing scope once the OnStart method is called. A 'ManualResetEvent' will keep the service open for you.

Use member:

ManualResetEvent stop = new ManualResetEvent(false);

Try this in your main Start():

do
{
    try
    {
         _app = new EmailReportApp();
         _app.Start();
    }
    catch(Exception e)
    {
        ... handle error or log however you want
    }
}
while(!stop.WaitOne(0, false))

in Stop(), make sure to do stop.Set()

a_schimpf
  • 745
  • 1
  • 5
  • 16
  • What's the point of catching and swallowing exceptions here? If the code isn't working properly, it's going to be even harder to figure out why if you can't get any exceptions. – Cody Gray - on strike May 31 '13 at 14:17
  • i put a '...' to mean you can put whatever you want there to error log or handle the erro. – a_schimpf May 31 '13 at 14:18
  • @a_schimpf am I missing something as when I write this it has no idea what stop watch is. – korrowan May 31 '13 at 15:15
  • sorry! i accidentally threw that stopwatch thing in there. i edited the code. – a_schimpf May 31 '13 at 15:16
  • @a_schimpf So I just plug that into my onstart exactly like that? Do I keep the code I had in there? The While statement is that how it is supposed to look? – korrowan May 31 '13 at 15:22
  • get rid of anything related to your servicetimer. get rid of all your code in onstart(). put this code in your onstart() function. in onstop(), do stop.Set(). the while statement is correct. – a_schimpf May 31 '13 at 15:26
  • @a_schimpf okay and I am going to guess that ManuelResetEvent needs System.Threading? – korrowan May 31 '13 at 15:32
  • yes, it will. in my own service, i actually created a run() thread from my onStart() function. then in the run() thread, I put the code above. – a_schimpf May 31 '13 at 15:36
  • @a_schimpf well that did it! I caught my error now too which wouldn't happen because it would just shut off. – korrowan May 31 '13 at 15:41
  • the cool thing about using a ManualResetTimer is that you can change its first argument to do a timeout, which blocks the thread until that time has elapsed. – a_schimpf May 31 '13 at 15:50