C# WPF how to ensure application keeps running 24/7

Jeff Heilman
Jeff Heilman used Ask the Experts™
on
I have a simple C# WPF application that shows production data in a datagrid that is bound to a tableadapter in a dataset linked to a SQL database table.  The only function is to display this information 24/7, it is not used to add or edit data.  My question is pretty general, what is the best way to ensure this application keeps running?  Every now and then it will stop working until I reopen the application.  Perhaps the way to handle it is to just relaunch the app any time it throws an exception?  The only message I get right now when it crashes is "Production Counter has stopped working.".

I'm new to C# and I am interested in your opinions/sample code/ideas, I'm looking to learn.  Thank you!

namespace ProductionCounter
{

    public partial class MainWindow : Window
    {
        public DispatcherTimer _timer = null;
        public MainWindow()
        {
            InitializeComponent();
            Initializeload();

            // Start the timer to refresh every 10000ms thereafter (change as required)
            _timer = new DispatcherTimer();
            _timer.Tick += Each_Tick;
            _timer.Interval = new TimeSpan(0, 0, 0, 0, 10000);
            _timer.Start();

            var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
            lblVersion.Content = string.Format("Version {0}", version);

            string machineName = Environment.MachineName;            
            lblMachineName.Content = machineName;
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            Initializeload();
        }

        private void Each_Tick(object o, EventArgs sender)
        {
             Initializeload();
        }

        private void Initializeload()
        {
            
                string machineName = System.Environment.MachineName;

                string connString = ConfigurationManager.ConnectionStrings["ProductionCounter.Properties.Settings.MyConnectionString"].ConnectionString;

                SqlDataAdapter da = new SqlDataAdapter("Select Department From tblQMSTerminalID WHERE TerminalID = @mach", connString);
                da.SelectCommand.Parameters.AddWithValue("@mach", machineName);
                DataSet ds = new DataSet();
                da.Fill(ds);
                string pl = ds.Tables[0].Rows[0]["Department"].ToString();
                lblProdLine.Content = pl;

                SqlDataAdapter sa = new SqlDataAdapter("SELECT MAX(UPWHID) AS MaxOfUPWHID, Shift, Dept, MAX(ShiftDate) AS MaxShiftDate, " +
                    "MIN(StartTime) AS MinStartTime FROM tblQMSUPWH WHERE Dept = @pline GROUP BY Dept, Shift", connString);
                sa.SelectCommand.Parameters.AddWithValue("@pline", pl);
                DataSet sd = new DataSet();
                sa.Fill(sd);
                string shift = sd.Tables[0].Rows[0][1].ToString();
                string sdate = sd.Tables[0].Rows[0][3].ToString();
                lblShift.Content = shift;
                lblDate.Content = Convert.ToDateTime(sdate);

                SqlDataAdapter pa = new SqlDataAdapter("SELECT Dept, Shift, ShiftDate, FLOOR(SUM(RunningGoal)) AS Target, SUM(UnitsProd) AS Produced " +
                    "FROM vw_PRODCOUNTER_HourlyProduction WHERE Dept = @pline AND Shift = @shift AND ShiftDate = @sdate GROUP BY Dept, Shift, ShiftDate", connString);
                pa.SelectCommand.Parameters.AddWithValue("@pline", pl);
                pa.SelectCommand.Parameters.AddWithValue("@shift", shift);
                pa.SelectCommand.Parameters.AddWithValue("@sdate", sdate);
                DataSet pd = new DataSet();
                pa.Fill(pd);
                string prod = pd.Tables[0].Rows[0][4].ToString();
                string target = pd.Tables[0].Rows[0][3].ToString();
                txtProduced.Text = prod;
                txtTarget.Text = target;
          
        }
    }
}

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
You may create recurrent job in Windows Task Scheduler. It allows to start the application after the login and restart each time it exits or crashes.

Application exceptions may be solved later... You just have to save them to a log file for analysis. Google for NLOG.
Chinmay PatelChief Technology Ninja
Distinguished Expert 2018

Commented:
Hi Jeff,

If I wanted to make sure that my app is kept running 24x7 and it is a mission critical app, I would rather keep it under a check using a Windows Service(running with Network Service account to save you the trouble of managing a dedicated Service Account - though, depending upon your requirements, you might want to cross check with your IT Admin/Security folks). While it is a bit complex to implement (If you are new to C#), in long term, you will rip the benefits.

I personally have never used this and I think I will never use it (I dunno why, I think I would rather use my own framework) but many swear by a service hosting framework called TopShelf http://topshelf-project.com/, you might want to check it out.

PS: If you are new to C# :D... this is a great learning opportunity as well.

Regards,
Chinmay.
Windows Service is a bad choice in this case because it cannot have UI so you have to maintain two applications in such case - 1. The Windows Service and 2. The UI running 24/7 as a front-end for the Windows service which in turn is easier to implement as one interactive application. So we are back in your WPF application and Windows Task Scheduler...

Of course, the service can produce web content and you may use web browser as a front-end to display it or you may code it as ASP.NET application but that's not task which could have simple and straight forward implementation at this phase.
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Jeff HeilmanBusiness Systems Mgr

Author

Commented:
pcelba, I looked at the Task Scheduler and didn't see an option for Recurrent Job.  Can you elaborate just a bit on this?  Thanks.
Jeff HeilmanBusiness Systems Mgr

Author

Commented:
Thank you for the link Chinmay, I'll definitely check it out.
Éric MoreauSenior .Net Consultant
Top Expert 2016

Commented:
You could restart the application by using code like this:
System.Diagnostics.Process.Start(Application.ResourceAssembly.Location);
Application.Current.Shutdown();

Open in new window

Jeff HeilmanBusiness Systems Mgr

Author

Commented:
I just stumbled across that a little while ago Eric.  Could I put that in a catch?
Senior .Net Consultant
Top Expert 2016
Commented:
probably yes but is your application becoming just too unstable to recover? I would put all the code of Initializeload in a try...catch. It would probably keep the application alive.
Recurrent Job in Task Scheduler - try various Triggers settings one of them states "Repeat every X hours/minutes"
Settings allow to set what to do when the task fails.

So you may start the task every 5 minutes but do nothing when it is running already. This will restart the task automatically when it exits after exception. (Not all exceptions is possible to trap in TRY - CATCH)
Of course, the above recurrence is achievable by simple batch program with one loop which will start the EXE again and again when it exits.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial