forked from zTechSoul/WindowsSampleService
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMainService.cs
More file actions
121 lines (103 loc) · 3.65 KB
/
Copy pathMainService.cs
File metadata and controls
121 lines (103 loc) · 3.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
using NLog;
using System;
using System.Collections.Specialized;
using System.Configuration;
using System.ServiceProcess;
using System.Threading;
using System.Threading.Tasks;
namespace SampleService
{
/// <summary>
/// Actual service
/// </summary>
partial class MainService : ServiceBase
{
// !! the service should have NO constructor. All initialisation is to be performed in OnStart method !!
///<summary> This class logger </summary>
private Logger Log;
///<summary> A task in which business-code will run </summary>
private Task WorkerTask;
///<summary> Cancellation token for WorkerTask </summary>
private CancellationTokenSource TokenCreator;
///<summary> App-wide objects are stored here </summary>
private CommonObjects Commons;
///<summary> Service start method </summary>
protected override void OnStart(string[] args)
{
// initialise logger
this.Log = LogManager.GetLogger(this.ServiceName);
this.Log.Info(string.Format("{0}Launching service {1}...", Environment.NewLine, this.ServiceName));
try
{
this.Log.Info(string.Format("Settings loading for {0}...", this.ServiceName));
// Here we take sattings form .config file
NameValueCollection settingsCollection = ConfigurationManager.AppSettings;
// Create new instance of common objects
this.Commons = new CommonObjects(settingsCollection);
this.Log.Info("Settings are loaded.");
this.TokenCreator = new CancellationTokenSource();
this.WorkerTask = new Task(this.StartAction, this.TokenCreator.Token, TaskCreationOptions.LongRunning);
this.WorkerTask.Start();
}
catch (Exception ex)
{
this.Log.Error(string.Format("Error on start of service {0}: {1}.", this.ServiceName, ex));
}
}
///<summary> Stopping service method </summary>
protected override void OnStop()
{
this.Log.Info(string.Format("Stopping service {0}: ...", this.ServiceName));
bool finishedSuccessfully = false;
try
{
// Вызываем завершение таска
this.TokenCreator.Cancel();
var timeout = TimeSpan.FromSeconds(5);
finishedSuccessfully = this.WorkerTask.Wait(timeout);
}
catch (Exception ex)
{
this.Log.Error(string.Format("Exception on stopping service: {0}{1}"
, Environment.NewLine, ex));
}
finally
{
if (finishedSuccessfully == true)
this.Log.Info(string.Format("Service {0} stopped successfully.", this.ServiceName));
}
}
///<summary> Method where you launch worker Task </summary>
private void StartAction()
{
// flag indicating exception
bool exception = false;
// in case of exception the cycle will wait for some time and then launch the Task once again
do
{
try
{
if (exception == true)
this.Log.Info("Service after exception ...");
exception = false;
MainAction actor = new MainAction(Commons);
Task trier = new Task(actor.Act, this.TokenCreator.Token, TaskCreationOptions.LongRunning);
trier.Start();
this.Log.Info("Service launched successfully.");
// wait for the Task to finish
// if there will be exceptions, the DO will be processed again
trier.Wait();
}
catch (Exception ex)
{
exception = true;
this.Log.Error(string.Format("Exception while processing worder task: {0}{1}", Environment.NewLine, ex));
this.Log.Error(string.Format("Will wait after exception for: {0} ...",
this.Commons.Settings.OnExceptionDelay.ToString("HH:mm:ss")));
Thread.Sleep(this.Commons.Settings.OnExceptionDelay);
}
}
while (exception == true);
}
}
}