C# WPF how to ensure application keeps running 24/7
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; } }}
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 Patel
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.
Pavel Celba
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.
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)
Pavel Celba
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.
Application exceptions may be solved later... You just have to save them to a log file for analysis. Google for NLOG.