Reputation: 2107
Really stuck with trying to get windows services to count through to ten seconds (accurately) and print each time it loops through to a text file.
I've read a number of entries that Timer
is not the way to go, however I'm very new to C# and cannot figure out how else you would go about this.
I am unsure how to fetch the counter timer (if it works) to only run through six or so times and how to output this to the text file specified within OnStart.
EDIT: there will be next to no CPU available for this.
Any help would be greatly appreciated.
Current code shown below, the debug bit is so I can test it without having to install.
public partial class CountDown : ServiceBase
{
public bool RunMyTimer = true;
public int DelayMyTimer = 10000; // ten seconds
private int TimerControl = 0;
public TrapModule()
{
InitializeComponent();
}
// debugging to check whether OnStart works
public void OnDebug()
{
OnStart(null);
}
protected override void OnStart(string[] args)
{
// begin service + putting a file
System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "OnStart.txt");
}
protected override void OnStop()
{
// stop service
}
//Time Keeping
public class Timer1
{
public long counter = 0;
public System.Threading.Timer stopWatch = null;
public bool enabled = false;
}
private void Reset(object state)
{
Timer1 ts = (Timer1)state;
long timerCount = ts.counter;
if (ts.counter >= Int64.MaxValue - 1)
{
ts.counter = 0;
ts.counter = ts.counter + 1;
}
if (RunMyTimer)
{
ts.stopWatch.Change(TimerControl, DelayMyTimer);
}
else
{
ts.stopWatch.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
}
Upvotes: 1
Views: 736
Reputation: 46052
With Windows services, you have to start some kind of thread in the OnStart
method in order for the service to keep running. If you don't do this, the service will start and immediately quit once it's installed and executed from the Services console. Fortunately, you're wanting to run a timer, which can satisfy this condition.
Below is some code I've written and tested to achieve what I understand you to be asking for.
public partial class CountDown : ServiceBase
{
public CountDown()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
_fs = System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "OnStart.txt");
_timer = new System.Timers.Timer(1000);
_timer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimerElapsed);
_timer.AutoReset = true;
_timer.Start();
}
protected override void OnStop()
{
_fs.Close();
_timer.Close();
}
private void OnTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
{
var message = String.Format("{0} - Count #{1}\n", DateTime.Now, _counter++);
var bytes = System.Text.Encoding.ASCII.GetBytes(message);
_fs.Write(bytes, 0, bytes.Length);
}
private System.Timers.Timer _timer;
private System.IO.FileStream _fs;
private int _counter;
}
Note that timing on Windows systems is not accurate. In the example, I've specified 1000 milliseconds as the timer interval, but this will not guarantee that the Elapsed
callback will be executed precisely every second. It'll be close, but not on the nose.
Here's the example output from my OnStart.txt file:
8/5/2014 10:59:26 AM - Count #0
8/5/2014 10:59:27 AM - Count #1
8/5/2014 10:59:28 AM - Count #2
8/5/2014 10:59:29 AM - Count #3
8/5/2014 10:59:30 AM - Count #4
8/5/2014 10:59:32 AM - Count #5
8/5/2014 10:59:33 AM - Count #6
8/5/2014 10:59:34 AM - Count #7
8/5/2014 10:59:35 AM - Count #8
8/5/2014 10:59:36 AM - Count #9
8/5/2014 10:59:37 AM - Count #10
HTH
Upvotes: 1