I am new To windows service. I need a windows service that reads an entry from a table from database. I have a CONSOLE APP where I add new project WINDOWS SERVICE. I already have a method that access the database, and other methods. I can put a thread on start that reads the database. Where do I put the thread? ( how can I do that). Where on WINDOWS SERVICE I add those methods? I have the Windows Service like this:
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
do
{
thread.start();
bool variab = readFromDatabase (Database table);
}
}
protected override void OnStop()
{
}
I suggest that you create a class in which you do everything you need and create in in the service:
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
YourClass cl = new YourClass();
cl.DoWhatYouNeed(...);
}
protected override void OnStop()
{
}
This gives you opportunity to run and test your class separate from service, maybe during debug release.
With windows services usually a method is created to execute the main loop of the service, in a separated thread. Otherwise the service could become unresponsive. For example, you can have a method called MainLoop to execute the service logic. Use the OnStart method only to do the initializing tasks, such as read configuration values or start the threads of the service. And use the OnStop to executing cleaning tasks, stopping threads, etc...
Thread _workerThread;
bool _shouldStop;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try{
_workerThread = new Thread(new ThreadStart(MainLoop));
_shouldStop = false;
_workerThread.Start();
}
catch{}
}
private void MainLoop()
{
while (!_shouldStop)
{
try{
//your logic here
}
catch{}
}
}
protected override void OnStop()
{
_shouldStop = true;
}
You must put your code or class, which contain data access logic in OnStart method
Related
This question already has answers here:
Better way to constantly run function periodically in C#
(3 answers)
Closed 2 years ago.
Id like to build a windows Service in C#.
This service needs to be run periodically like every 10s.
Questions:
What is the difference between Timers.timer and Threading.timer?
How can I call CheckingThings with parameters?
If i run this code, it does invoke CheckingThings more than once every second like declared in here:
_timer = new Timer(new TimerCallback(CheckingThings), autoEvent, 5000, 1000);
Here is what i've got so far:
public partial class WindowsService1 : ServiceBase
{
// Logging
private static Serilog.Core.Logger _logEvent;
public WindowsService1()
{
InitializeComponent();
}
public void OnDebug() {
OnStart(null);
}
protected override void OnStart(string[] args)
{
//Logging
try {
_logEvent = new LoggerConfiguration()
.WriteTo.File(AppDomain.CurrentDomain.BaseDirectory + #"Logs\Logfile.txt", rollingInterval: RollingInterval.Month)
.CreateLogger();
}
catch (Exception e)
{
_logEvent.Error("The logging service is not working as expected: {errorMsg}", e);
}
try
{
// initializing some data here
var autoEvent = new AutoResetEvent(true);
while (true)
{
_timer = new Timer(new TimerCallback(CheckingThings), autoEvent, 5000, 1000);
}
}
catch (Exception e) {
_logEvent.Error("An error occured while initializing service: {0}", e);
}
}
private static void CheckingThings(object stateInfo)
AutoResetEvent autoEvent = (AutoResetEvent)stateInfo;
//These things needs to run periodically every 10s
}
protected override void OnStop()
{
_logEvent.Information("Stopping Service ...");
}
}
Here's a skeleton for a service class that does something every minute, using a System.Timers.Timer:
public partial class XService : ServiceBase
{
private Timer _minute = new Timer(60000);
public XService()
{
InitializeComponent();
_minute.Elapsed += Minute_Elapsed;
}
//this is async because my 'stuff' is async
private async void Minute_Elapsed(object sender, ElapsedEventArgs e)
{
_minute.Stop();
try
{
//stuff
}
catch (Exception ex)
{
//log ?
}
finally
{
_minute.Start();
}
}
protected override void OnStart(string[] args)
{
_minute.Start(); //this or..
Minute_Elapsed(null, null); //..this, if you want to do the things as soon as the service starts (otherwise the first tick will be a minute after start is called
}
...
I typically stop my timers while I do my thing - no point starting a job that takes 10 minutes and then another one a minute later, hence the stop/try/finally/start pattern
Edit:
Here's the tail part of the class and how it's started/launched both in debug (inside visual studio) and in release (as an installed windows service):
//just an adapter method so we can call OnStart like the service manager does, in a debugging context
public void PubOnStop()
{
OnStop();
}
}// end of XService class
static void Main(string[] args)
{
#if DEBUG
new XService().PubStart(args);
Thread.Sleep(Timeout.Infinite);
#else
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new XService()
};
ServiceBase.Run(ServicesToRun);
#endif
}
I have a windows service that I made for MY server...
I need to check every minute if there is some new info in my SQL Database.
So I made a windows service that create a Timer with interval of 1 minute.
But The windows service set the timer and ending the run.
It's goes like this:
Starting Service
Setting Timer with interval
Finishing and exiting Service <-- I want to keep it alive
As you can see the Service exit and I want the Windows service to run every minute without stopping....
I can see in the Event Viewer that there are the "Service started successfully." And the "Service stopped successfully."
What should I do?
P.S : I thought Timer should work with out exit... or may I wrong?
CODE:
Windows service:
static void Main(string[] args)
{
try
{
Utils.SetConfigFile();
var ServiceToRun = new TaoTimer();
ServiceToRun.Start();
}
catch (Exception ex)
{
EventLog.WriteEntry("Application", ex.ToString(), EventLogEntryType.Error);
}
}
TaoTimer:
public partial class TaoTimer : ServiceBase
{
List<TimerModel> timerList;
public TaoTimer()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
EventLog.WriteEntry("Started");
}
public void SetTimer(TimerModel timerModel)
{
int minute = 1000 * 60;
try
{
AlertTimer at = new AlertTimer(timerModel, minute);
at.Start();
}
catch
{
}
}
protected override void OnStop()
{
EventLog.WriteEntry("Stopped");
}
protected override void OnPause()
{
EventLog.WriteEntry("Paused");
}
protected override void OnContinue()
{
EventLog.WriteEntry("Continuing");
}
protected override void OnShutdown()
{
EventLog.WriteEntry("ShutDowned");
}
public void Start()
{
SetTimerList();
}
protected void SetTimerList()//Read Config from xml and start the timer
{
XElement root = XElement.Load(#"C:\TaoTimer\Data.xml");
timerList = new List<TimerModel>(from d in root.Descendants("Timer")
select new TimerModel(
d.Element("Id").Value.ToString(),
d.Element("Name").Value.ToString(),
d.Element("InterVal").Value.ToString(),
d.Element("TimeFormat").Value.ToString(),
d.Element("Day").Value.ToString(),
d.Element("TimeStamp").Value.ToString()));
timerList.ForEach(i => SetTimer(i));
}
}
AlertTimer:
public class AlertTimer
{
static System.Timers.Timer aTimer = new System.Timers.Timer();
public AlertTimer(TimerModel timerModel, int milliseconds)
{
aTimer.Elapsed += new ElapsedEventHandler((sender, e) => OnTimedEvent(sender, e, timerModel));
aTimer.Interval = milliseconds;
}
public void Start()
{
aTimer.Enabled = true;
}
public static void OnTimedEvent(object source, ElapsedEventArgs e, TimerModel timerModel)
{
getAbsenceContacts.Start();<-- NEVER GETS HERE....
}
}
You're not actually starting your service. You're calling a method named Start, which is not part of the Windows Service class hierarchy it's just a method you've defined. Your method runs and finishes, so the service exits.
Try this:
static void Main(string[] args)
{
try
{
Utils.SetConfigFile();
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new TaoTimer()
};
ServiceBase.Run(ServicesToRun);
}
catch (Exception ex)
{
EventLog.WriteEntry("Application", ex.ToString(), EventLogEntryType.Error);
}
}
public partial class TaoTimer : ServiceBase
{
...
protected override void OnStart(string[] args)
{
SetTimerList();
EventLog.WriteEntry("Started");
}
....
}
and remove the Start method from TaoTimer entirely.
You need to store your AlertTimer instances in something that will last the lifetime of the service (e.g. in a List<AlertTimer> declared as a field inside TaoTimer.
It's only really alluded to in the documentation for Timer that timer's, in and of themselves, don't prevent themselves from being garbage collected. The example says:
// Normally, the timer is declared at the class level,
// so that it stays in scope as long as it is needed.
// If the timer is declared in a long-running method,
// KeepAlive must be used to prevent the JIT compiler
// from allowing aggressive garbage collection to occur
// before the method ends. You can experiment with this
// by commenting out the class-level declaration and
// uncommenting the declaration below; then uncomment
// the GC.KeepAlive(aTimer) at the end of the method.
//System.Timers.Timer aTimer;
Now, whilst your timer's are declared at the class level inside of your AlertTimer class, there's nothing to stop the AlertTimer instances, themselves, from being collected. And the GC only keeps things alive that are transitively reachable. Once the AlertTimer instances are collectible, so are your Timer objects.
I have this simple windows service that is part of a browser game. What it does is check against database and if needed updates some rows. These actions takes about .5 to 1 second.
The data it reads is a date which tells if an item should be updated.
It works perfectly, however it is always around 25 seconds late. If I add an item to the queue, and that item is completed at 15:00:00, the service will update it at 15:00:25ish.
I've tried using threading.timer, a single thread and timers.timer and all works in the same way. I've also tried stopping the timer while the elapsed was running, although it takes less than a second so it should not be a problem.
I've also tried to attach the service to a debugger, and the same thing happens UNLESS I put a breakpoint. Then it happens as soon as it hits the breakpoint and i press f5 to continue.
Can anyone shed some light as to why the service seems to be behind? And a possible fix.
I was thinking I ran out of thread but I have a good 1000 left, so I'm kinda blank.
Please ask if you need more details, so I can provide.
I'm using .net 4.0 / C#
Threading.Thread
public partial class Service : ServiceBase
{
Thread thread;
public Service()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
thread = new Thread(DoWork);
thread.Start();
}
private static void DoWork()
{
while (true)
{
//finish workingqueueitems
WorkingQueue.ProcessFinishedItems();
Thread.Sleep(1000);
}
}
protected override void OnStop()
{
thread.Abort();
}
}
Timers.Timer
public partial class Service : ServiceBase
{
System.Timers.Timer workingQueueTimer;
public Service()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
workingQueueTimer = new System.Timers.Timer();
workingQueueTimer.Elapsed += new ElapsedEventHandler(workingQueueTimer_Elapsed);
workingQueueTimer.Interval = 1000;
workingQueueTimer.Enabled = true;
}
void workingQueueTimer_Elapsed(object sender, ElapsedEventArgs e)
{
workingQueueTimer.Enabled = false;
DoWork();
workingQueueTimer.Enabled = true;
}
private static void DoWork()
{
//finish workingqueueitems
WorkingQueue.ProcessFinishedItems();
}
protected override void OnStop()
{
workingQueueTimer.Stop();
workingQueueTimer.Dispose();
}
}
The problem could be due to:
your DoWork() method takes 25 sec to complete
You are seeing the db data cached in someway or a transaction is delaying it
your method WorkingQueue.ProcessFinishedItems() is taking the wrong rows to update
if your service and db are in separeted machine they have a different time clock of 25 sec
I've googled this one
but when i'm trying to apply it i get an error. So install/uninstall works fine, but service itself just doesn't start and after timeout it says that service doesn't respond. I don't know why. When i'm attaching to process it even doesn't enter into Main() method, static constructors and so on. I've used this addon for attach.
public static void Main()
{
AppDomain.CurrentDomain.UnhandledException += OnException;
if (Environment.UserInteractive)
{
AskUserForInstall();
}
else
{
ServiceBase.Run(new NotificatorService());
}
}
Service is also very simple:
using System.ServiceProcess;
using System.Windows;
namespace AZNotificator
{
public partial class NotificatorService : ServiceBase
{
static NotificatorService()
{
int x = 5;
}
public NotificatorService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
MessageBox.Show("Hello");
}
protected override void OnStop()
{
}
}
}
You can not call MessageBox.Show("Hello"); from the windows service since the service does not have the GUI.
If you want to do some interaction from the windows service have a look at this article
http://msdn.microsoft.com/en-us/library/ms683502(VS.85).aspx
So remove MessageBox.Show("Hello"); from your OnStart method and your service should start just fine.
I have a service that creates a thread with a loop that should run until the mutex is signalled by another process. I have the following in my service code
private readonly Mutex _applicationRunning = new Mutex(false, #"Global\HsteMaintenanceRunning");
protected override void OnStart(string[] args)
{
new Thread(x => StartRunningThread()).Start();
}
internal void StartRunningThread()
{
while (_applicationRunning.WaitOne(1000))
{
FileTidyUp.DeleteExpiredFile();
_applicationRunning.ReleaseMutex();
Thread.Sleep(1000);
}
}
Now I have a console application that should claim the mutex and force the while loop to be exited
var applicationRunning = Mutex.OpenExisting(#"Global\HsteMaintenanceRunning");
if (applicationRunning.WaitOne(15000))
{
Console.Write("Stopping");
applicationRunning.ReleaseMutex();
Thread.Sleep(10000);
}
When the console application tries to open the mutex I get the error "The wait completed due to an abandoned mutex." Whats wrong here?
I recommend that you use the Service's built-in stop signal rather than a mutex. The mutex class is more appropriate for managing exclusive access to a shared resource, which is not what's going on here. You could also use a system event but since services already have a built-in mechanism for signaling when they're stopping, why not use it?
Your service's code would look like this:
bool _stopping = false;
Thread _backgroundThread;
protected override void OnStart(string[] args)
{
_backgroundThread = new Thread(x => StartRunningThread());
_backgroundThread.Start();
}
protected override void OnStop()
{
_stopping = true;
_backgroundThread.Join(); // wait for background thread to exit
}
internal void StartRunningThread()
{
while (!stopping)
{
FileTidyUp.DeleteExpiredFile();
Thread.Sleep(1000);
}
}
Then, your console application would need to use the framework's ServiceController class to send the shut down message to your service:
using System.ServiceProcess;
...
using (var controller = new ServiceController("myservicename")) {
controller.Stop();
controller.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(15.0));
}