I am thinking about writing a windows service that will turn a certain functionality on or off at times specified by the user (using a configuration utility I will provide). Basically, the user would specify certain times that the PC would go into "work-only" mode (blocking Facebook and other distracting sites), and then when those times are up the PC will return to normal mode.
I have already come up with a few ways to create the "work-only" mode, but what I am struggling with is how to know when to go into and out of that mode. I don't really want to work with threads and timers if I can avoid it since that seems like it would create an awful lot of overhead, so what I am looking for would be some way to either:
- Hook in to the Windows API if there is some kind of timeChanged() event to check against
- Use some sort of pre-built library for firing events at a specified time
- Some other method that I haven't thought of that is elegant and wonderful
Does anyone know the best way to do this?
I think you can achieve it quite well with a Windows Service as you mentioned. In one of our productions systems we have a windows service (different core functionality as the requested) implemented in the way below that is running safely for almost three years now.
Basically the aim of the following code is that the service executes certain method each time the internal timer (myTimer
) wakes-up.
Here below is a basic implementation. In this example your core functionality should be placed at the method EvalutateChangeConditions
, that is supposed to be executed each 60 seconds. I would also provide a public method for your managing client(s) to know the current "working-mode".
public partial class MyService : ServiceBase
{
private System.Threading.Thread myWorkingThread;
private System.Timers.Timer myTimer = new System.Timers.Timer();
// [...] Constructor, etc
protected override void OnStart(string[] args)
{
// Do other initialization stuff...
// Create the thread and tell it what is to be executed.
myWorkingThread = new System.Threading.Thread(PrepareTask);
// Start the thread.
myWorkingThread.Start();
}
// Prepares the timer, sets the execution interval and starts it.
private void PrepareTask()
{
// Set the appropiate handling method.
myTimer.Elapsed += new System.Timers.ElapsedEventHandler(myTimer_Elapsed);
// Set the interval time in millis. E.g.: each 60 secs.
myTimer.Interval = 60000;
// Start the timer
myTimer.Start();
// Suspend the thread until it is finalised at the end of the life of this win-service.
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
}
void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
// Get the date and time and check it agains the previous variable value to know if
// the time to change the "Mode" has come.
// If does, do change the mode...
EvalutateChangeConditions();
}
// Core method. Get the current time, and evaluate if it is time to change
void EvalutateChangeConditions()
{
// Retrieve the config., might be from db? config file? and
// set mode accordingly.
}
protected override void OnStop()
{
// Cleaning stuff...
}
}
If there's no reason that Windows Task Scheduler won't work for you, I would recommend you use that.
If you don't want to use task scheduler, I would have a simple loop which checks for any upcoming events (lock/unlock sites) and execute any which are due. If no events are coming up, sleep for a long period (Thread.Sleep()).
I haven't looked into any side effects of long sleeps, but a sleep time of one minute shouldn't consume much in the way of resources. If it wasn't a service, I would probably put in a termination check, but I assume that the service isn't meant to terminate.
来源:https://stackoverflow.com/questions/10575900/c-sharp-windows-service-with-awareness-of-system-time