@@ -12,117 +12,119 @@ namespace ServMon
1212 class Program
1313 {
1414 /// <summary>
15- /// Sleep interval in minutes .
15+ /// Sleep interval in seconds .
1616 /// </summary>
1717 private static int execInterval ;
18- private static bool writeState = true ;
18+ private static volatile bool writeState = true ;
1919
20- static void Main ( string [ ] args )
20+ static async Task Main ( string [ ] args )
2121 {
22- var workerThreads = new List < Thread > ( ) ;
22+ using var cts = new CancellationTokenSource ( ) ;
23+ var token = cts . Token ;
2324
24- Console . WriteLine ( "ServMon started. Press ENTER to stop." ) ;
25+ Console . CancelKeyPress += ( _ , e ) =>
26+ {
27+ e . Cancel = true ;
28+ cts . Cancel ( ) ;
29+ } ;
30+
31+ Console . WriteLine ( "ServMon started. Press Ctrl+C to stop." ) ;
2532 Console . WriteLine ( ) ;
2633
27- var schedulerThread = new Thread ( ( ) =>
34+ try
2835 {
29- try
30- {
31- ServManager . Instance . ReadConfig ( ) ;
32- }
33- catch ( Exception ex )
34- {
35- LogHelper . WriteLog ( true , ex ) ;
36- return ;
37- }
36+ ServManager . Instance . ReadConfig ( ) ;
37+ }
38+ catch ( Exception ex )
39+ {
40+ LogHelper . WriteLog ( true , ex ) ;
41+ return ;
42+ }
3843
39- execInterval = ServManager . Instance . Interval ;
44+ execInterval = ServManager . Instance . Interval ;
45+
46+ Console . WriteLine ( "Default exec interval: {0} seconds" , execInterval ) ;
47+ Console . WriteLine ( "Begin instrumentation..." ) ;
48+ Console . WriteLine ( ) ;
4049
41- Console . WriteLine ( "Default exec interval: {0} seconds" , execInterval ) ;
42- Console . WriteLine ( "Begin instrumentation..." ) ;
43- Console . WriteLine ( ) ;
50+ var items = ServManager . Instance . Items ;
51+ var workerTasks = new List < Task > ( ) ;
4452
45- var items = ServManager . Instance . Items ;
46- foreach ( var item in items )
53+ foreach ( var item in items )
54+ {
55+ if ( item . Value . Enabled )
4756 {
48- if ( item . Value . Enabled )
57+ var serv = item . Value ;
58+ var task = Task . Run ( async ( ) =>
4959 {
50- var workerThread = new Thread ( ( ) =>
60+ bool smsSent = false ;
61+ while ( ! token . IsCancellationRequested )
5162 {
52- bool smsSent = false ; // SMS won't be sent successively, will always skip one instance for consecutive failures.
53- while ( true )
54- {
55- var serv = item . Value ;
56- //Console.WriteLine();
57- Console . WriteLine ( "{0}: Started" , serv . Name ) ;
63+ Console . WriteLine ( "{0}: Started" , serv . Name ) ;
5864
59- var success = serv . Success ;
60- var response = serv . Execute ( ) ;
61- if ( ! response . Success )
65+ var success = serv . Success ;
66+ var response = serv . Execute ( ) ;
67+ if ( ! response . Success )
68+ {
69+ if ( ! string . IsNullOrEmpty ( response . Message ) )
70+ Console . WriteLine ( "{0}: FAILED. {1}" , serv . Name , response . Message ) ;
71+ else
72+ Console . WriteLine ( "{0}: FAILED." , serv . Name ) ;
73+ var mail = new MailSender ( ) ;
74+ mail . Subject = string . Format ( "ServMon: {0} - Check FAILED" , serv . Name ) ;
75+ mail . Message = string . Format ( "Service: {0}<br/>Time: {1}<br/>Error: {2}<br/><br/>Trace: {3}" , serv . Name , serv . LastUpdate , response . Message , response . StackTrace ) ;
76+ mail . To = ( ServManager . Instance . MailSettings . To + "," + serv . ToEmails ) . Trim ( ) . TrimEnd ( ',' ) ;
77+ mail . Send ( ) ;
78+ Console . WriteLine ( "{0}: Email sent to {1}" , serv . Name , mail . To ) ;
79+
80+ var smsTo = ( ServManager . Instance . SmsSettings . To + "," + serv . ToNumbers ) . Trim ( ) . TrimEnd ( ',' ) ;
81+ if ( ServManager . Instance . SmsSettings . Enabled && serv . EnableSms && ! string . IsNullOrEmpty ( smsTo ) )
6282 {
63- if ( ! string . IsNullOrEmpty ( response . Message ) )
64- Console . WriteLine ( "{0}: FAILED. {1}" , serv . Name , response . Message ) ;
83+ if ( ! smsSent )
84+ {
85+ var sms = new SmsSender ( ) ;
86+ sms . To = smsTo ;
87+ sms . Message = string . Format ( "{0} - FAILED, pls chk. %0AError: {1}" , serv . Name , response . Message ) ;
88+ sms . Send ( ) ;
89+
90+ Console . WriteLine ( "{0}: SMS sent to {1}" , serv . Name , smsTo ) ;
91+ smsSent = true ;
92+ }
6593 else
66- Console . WriteLine ( "{0}: FAILED." , serv . Name ) ;
67- var mail = new MailSender ( ) ;
68- mail . Subject = string . Format ( "ServMon: {0} - Check FAILED" , serv . Name ) ;
69- mail . Message = string . Format ( "Service: {0}<br/>Time: {1}<br/>Error: {2}<br/><br/>Trace: {3}" , serv . Name , serv . LastUpdate , response . Message , response . StackTrace ) ;
70- mail . To = ( ServManager . Instance . MailSettings . To + "," + serv . ToEmails ) . Trim ( ) . TrimEnd ( ',' ) ;
71- mail . Send ( ) ;
72- Console . WriteLine ( "{0}: Email sent to {1}" , serv . Name , mail . To ) ;
73-
74- var smsTo = ( ServManager . Instance . SmsSettings . To + "," + serv . ToNumbers ) . Trim ( ) . TrimEnd ( ',' ) ;
75- if ( ServManager . Instance . SmsSettings . Enabled && serv . EnableSms && ! string . IsNullOrEmpty ( smsTo ) )
7694 {
77- if ( ! smsSent )
78- {
79- var sms = new SmsSender ( ) ;
80- sms . To = smsTo ;
81- sms . Message = string . Format ( "{0} - FAILED, pls chk. %0AError: {1}" , serv . Name , response . Message ) ;
82- sms . Send ( ) ;
83-
84- Console . WriteLine ( "{0}: SMS sent to {1}" , serv . Name , smsTo ) ;
85- smsSent = true ;
86- }
87- else
88- {
89- smsSent = false ;
90- }
95+ smsSent = false ;
9196 }
9297 }
93- else
94- {
95- Console . WriteLine ( "{0}: Success!" , serv . Name ) ;
96- smsSent = false ;
97- }
98-
99- if ( success != response . Success )
100- {
101- // Change in status, write state to json file
102- writeState = true ;
103- }
98+ }
99+ else
100+ {
101+ Console . WriteLine ( "{0}: Success!" , serv . Name ) ;
102+ smsSent = false ;
103+ }
104104
105- //Console.WriteLine("{0}: Sleeping...", serv.Name);
106- Sleep ( serv . Interval ) ;
105+ if ( success != response . Success )
106+ {
107+ writeState = true ;
107108 }
108- } ) ;
109109
110- workerThreads . Add ( workerThread ) ;
110+ await SleepAsync ( serv . Interval , token ) ;
111+ }
112+ } , token ) ;
111113
112- workerThread . IsBackground = false ; // Always dependent to job threads // !forceExecute;
113- workerThread . SetApartmentState ( ApartmentState . STA ) ;
114- workerThread . Start ( ) ;
115- }
114+ workerTasks . Add ( task ) ;
116115 }
116+ }
117117
118+ // State writer task
119+ var stateWriterTask = Task . Run ( async ( ) =>
120+ {
118121 var jsonCheck = 0 ;
119- while ( true )
122+ while ( ! token . IsCancellationRequested )
120123 {
121124 jsonCheck += 10 ;
122- Sleep ( 10 ) ; // Check status changes every 10 seconds
125+ await SleepAsync ( 10 , token ) ;
123126 if ( writeState || jsonCheck > execInterval )
124127 {
125- // Build Json object
126128 var json = new JObject (
127129 new JProperty ( "services" ,
128130 new JArray (
@@ -144,26 +146,33 @@ from i in items.Values
144146 jsonCheck = 0 ;
145147 }
146148 }
147- } ) ;
148- schedulerThread . IsBackground = false ; // Always dependent to job threads // !forceExecute;
149- schedulerThread . SetApartmentState ( ApartmentState . STA ) ;
150- schedulerThread . Start ( ) ;
151- Console . ReadLine ( ) ;
152-
153- Console . WriteLine ( "Aborting Threads. Press wait..." ) ;
154- // Abort Scheduler Thread
155- schedulerThread . Abort ( ) ;
156- foreach ( var thread in workerThreads )
157- thread . Abort ( ) ;
149+ } , token ) ;
150+
151+ workerTasks . Add ( stateWriterTask ) ;
152+
153+ try
154+ {
155+ await Task . WhenAll ( workerTasks ) ;
156+ }
157+ catch ( OperationCanceledException )
158+ {
159+ // Expected on shutdown
160+ }
158161
159162 Console . WriteLine ( ) ;
160- Console . WriteLine ( "Processing stopped. Press ENTER to exit." ) ;
161- Console . ReadLine ( ) ;
163+ Console . WriteLine ( "Processing stopped gracefully." ) ;
162164 }
163165
164- private static void Sleep ( int interval = - 1 )
166+ private static async Task SleepAsync ( int interval , CancellationToken token )
165167 {
166- Thread . Sleep ( ( interval > 0 ? interval : execInterval ) * 1000 ) ;
168+ try
169+ {
170+ await Task . Delay ( ( interval > 0 ? interval : execInterval ) * 1000 , token ) ;
171+ }
172+ catch ( OperationCanceledException )
173+ {
174+ // Expected on cancellation
175+ }
167176 }
168177 }
169178}
0 commit comments