how to set timer for each different thread in window service - c#

trying to set timer for each different threads with different timings , as far as i know if we set a timer in main method the same will works for all the threads, so i want to know how to set timer for each different thread with out killing the threads, kindly advice on this please
static Timer _timer;
static void Main(string[] args)
{
_timer = new Timer(10000);
_timer.Enabled = true;
_timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
}
the above pasted code will do job for all of the threads will run for every ten sec, how ever all threads will run for every ten sec by the timer in main method, my concern is have to set timer for each thread with different timing
Summary:
why i asked like this question, here i have requirement of window service,what is to do means,For example in a window service having a three different threads(XYZ,ABC,PQR), if i start a service,all the three threads to be intialized and those threads should to be acts as For which based on timer settings which we are passing from the app config,these thread has to be fire based on the timings has setted,kindly advice

If you want to start some threads after a given time, you can use System.Threading.Timer.
int[] times = new int[] { 10000, 14000, 17000 };
foreach (int time in times)
{
System.Threading.Timer t = new System.Threading.Timer(MyTimerCallback, null, time, 0);
...
}
private void MyTimerCallback(object state)
{
//Do some awesome stuff
}

Have you tried to use the [ThreadStatic] attribute?
This attribute defines that the veriable it coupled with will not be shared between threads, and a copy of him will be created for each thread.
[ThreadStatic]
static Timer _timer;
void MyThreadStartMethod()
{
_timer=new Timer(value);
...
}
And also, i don't see any threads in your code. The Main method is called by the CLR to start the application, and runs each time in a different process.

Related

How to create an application loop in C#

I have a console server in C# that keeps running in a while(true) loop. But that takes > 50% CPU even if it is doing nothing. I tried Thread.Sleep it worked! Not eating my CPU anymore but, it do not resumes in the exact time specified and is not considered good practice. Am I doing the right thing? Or is there any other way than using while(true) and Thread.Sleep?
When you want to suspend thread for a while without consuming CPU resources, you usually use some WaitHandle (such as AutoResetEvent or ManualResetEvent) and call it's WaitOne() method to suspend thread until event that is supposed to wake it up occurs (e.g. key is pressed, new network connection arrives, asynchronous operation finishes, etc.).
To wake up thread periodically, you can use timer. I'm not aware of any timer in .NET Framework, that provides WaitHandle (of course you can easily create such class yourself), so have to use Timer and call AutoResetEvent.Set() manually on each tick in it's callback.
private static AutoResetEvent TimerWaitHandle = new AutoResetEvent(false);
static void Main()
{
// Initialize timer
var timerPeriod = TimeSpan.FromMilliseconds(500);
Timer timer = new Timer(TimerCallback, null, timerPeriod, timerPeriod);
while(true)
{
// Here perform your game logic
// Suspend main thread until next timer's tick
TimerWaitHandle.WaitOne();
// It is sometimes useful to wake up thread by more than event,
// for example when new user connects etc. WaitHandle.WaitAny()
// allows you to wake up thread by any event, whichever occurs first.
//WaitHandle.WaitAny(new[] { TimerWaitHandle, tcpListener.BeginAcceptSocket(...).AsyncWaitHandle });
}
}
static void TimerCallback(Object state)
{
// If possible, you can perform desired game logic here, but if you
// need to handle it on main thread, wake it using TimerWaitHandle.Set()
TimerWaitHandle.Set();
}
I can't comment, so i'll put it here.
Theorically with Thread.sleep(1) it won't use that much CPU.
You can get more info from this question/answer: What is the impact of Thread.Sleep(1) in C#?
You can use System.Threading.Timer class. It Provides a mechanism for executing a method on a thread pool thread at specified intervals.
Example
public void Start()
{
}
int dueTime = 1000;
int periodTS = 5000;
System.Threading.Timer myTimer = new System.Threading.Timer(new TimerCallback(Start), null, dueTime, periodTS);
This will call start method after 1 second from calling it and after that start will be called after every 5 second.
You can read more about Timer class here.

Is my Timer causing my application to hang?

I’ve been scratching my head for days about this problem. I’m trying to get a timer that restarts the application every 50s. The code basically fetches database items every 50s and does something. However it seems to hang overnight when there has been a long period of inactivity. I've just shown a skeleton of the code below. In the code also theres’s a connection to a mysql db, rest hhtpwebrequest, and a ssh using renci.ssh to get to another computer. All these are closed properly.
static void Main(string[] args)
{
Timer timer = new Timer(state => workDone(), null, 50000, 50000);
workDone();
}
private static void workDone()
{
//Hold program open for next cycle
Console.ReadLine();
}
Somewhere towards the end of my code i also used Console.ReadLine(); to hold the program open. Is there a reason why this should hang after a period of inactivity? I have a suspicion it’s my code but it may also be the linux box? Will post the whole code if need be. Thank you so much for all your help. Cheers.
I guess you are trying to do this:
private static Timer timer;
static void Main(string[] args)
{
timer = new Timer(state => workDone(), null, 0, 50000);
// Hold program open...
Console.ReadLine();
}
private static void workDone()
{
// Do work
}
I think that by blocking in the callback you'll eventually use up the threadpool.
From MSDN:
The method specified for callback should be reentrant, because it is called on ThreadPool threads. The method can be executed simultaneously on two thread pool threads if the timer interval is less than the time required to execute the method, or if all thread pool threads are in use and the method is queued multiple times.
In your example the time to execute the callback is taking indefinitely long as it is blocking while waiting for user input.
If you want to perform such computation, I suggest you to have one independent thread that will contain a Sleep(50000) call inside. The reason is that if your computation takes more than 50 seconds you might end up with an overhead.
So in your thread measure the start time, do your computation, measure the end time, then compute the computation time and do a sleep of 50 seconds - "computation time". Ensure that this number is positive and put a 10 second minimum sleep in order to let some slack to the other tasks if the computation was longer than 40 seconds.
Thread thread = new Thread(new ThreadStart(myThreadFunction)); thread.Start();
then:
public void myThreadFunction()
{
Stopwatch stopWatch = new Stopwatch();
while(someCondition) {
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
doWork();
stopWatch.Stop();
long elapsed = stopWatch.ElapsedMilliseconds;
if(elapsed < 10000) elapsed = 10000;
Thread.Sleep(elapsed);
}
}
**doWork() does not have the ReadLine call.

Perform a event certain so many times every so many seconds

I am currently working on a c# project where I need to perform a task so many times every so many seconds.
For example, write to the console 5 times every 1 second. How could I go about doing this.
Thanks for any help you can provide.
You can use a Timer and bind and event to the Timer.Elapsed event.
using System.Timers;
Sample code:
Timer timer = new Timer();
timer.Elapsed += (sender, eventArgs) =>
{
for (int i = 0; i < 5; i++)
{
Console.Write(i);
}
};
Is this an console application, or do you run this on another thread?
For short stuff like this, use a timer. There are two main ones to choose from:
System.Threading.Timer
And:
System.Windows.Forms.Timer
The former uses the ThreadPool, the latter uses UI events. They both expose the ability to specify and interval and either a callback method or event to attach to in order to put custom code.
For longer periods of inactivity, look into scheduling either with the Windows scheduler (the OS one) or a scheduling framework such as Quartz.NET.
Do note that the accuracy of the timers vary, but not really within margins that humans can detect :-)
Also note that the callback of the threaded timer will return on an arbitrary ThreadPool thread, so you could effectively end up "multi-threading" the code without realising it.
There is also System.Timers.Timer, it exposes an event. An article about the different timers available can be found here.
I don't think it will affect you, but it's still worth knowing - windows is not a real-time OS; if you ask for something to be done every X milliseconds, it won't be exact, as for how much it will be out depends on a variety of things.
You could create a thread to do it. Especially useful if you want to do a lot of processing! Here's an example of a thread doing work every 1s (1000ms):
public void Start()
{
running = true;
thread = new Thread(new ParameterizedThreadStart(ThreadFunction));
thread.Start();
}
public virtual void ThreadFunction(object o)
{
var insert = false;
while (running)
{
//Do work
Thread.Sleep(1000);
}
}
try this
While (true)
{
for (int i=0; i<5; i++)
{
console ("Hello");
}
//this will pause for 1 sec (1000msec)
Thread.sleep(1000);
}

Adjustable service timer in C#

I'm trying to write a Windows service that runs indefinitely. Windows forms and background programs for Linux don't seem too bad but maybe I'm just horribly inept at Windows Services. Unlike some other sleep or timer related questions I've dug through here, the time to wake up or sleep can be a regular interval, but isn't always such. The program reads from some data files that may instruct it to change its own schedule and this must take effect as of its next wake up time. It seemed quite easy as a console program and behaved perfectly there:
while (true)
{
// Calculate next time to run.
DateTime nextRun = NextWakeup();
TimeSpan nextTime = nextRun - DateTime.Now;
int sleepMs = (int)nextTime.TotalMilliseconds;
// Sleep until scheduled time
System.Threading.Thread.Sleep(sleepMs);
// Do a code cycle of more stuff here...
}
However, when I try to run it as part of a service so that it continues to be active while the user is logged out, the Service Manager stubbornly refuses to start it. I get the lovely 1053 error, "The service did not respond to the start or control request in a timely fashion."
A lot of answers to related questions here seem to suggest going with a timer at all costs over thread sleeping. If I did such a thing instead of the while/sleep combination, how would I go about changing the timer interval at each run? Or is this all perfectly fine and I'm going about setting up my service wrong?
Much thanks in advance!
Windows services must usually respond to a control request (ususally start/stop but also pause/resume) in 30seconds. This means that if you sleep the main thread in the OnStart your service will return the error you refer to.
The way to resolve your issue is to do your work on a separate thread, where you're free to sleep the thread in the way you describe. Just start this thread in the services' OnStart and you should be able to easily return within the 30 second limit.
As an aside, instead of while(true) you should consider the service being stopped must also return in that 30 second limit. If you have a thread sat sleeping the service will not shut down properly without either Aborting the thread (bad) or providing some mechanism for properly exiting the thread. This is exactly why most people go with the polling approach; the service can both determine whether its time to run, or determine whether a stop request has taken place. As long as this poll freqency is <30s the service will always shut down properly.
If you want to use timers its quite easy to do. I'd use System.Timers.Timer and changing its interval is as easy as mytimer.Inverval = nextTime.Seconds or similar.
I'd personally run the timer without AutoReset = false (so it doesn't restart the timer automatically) and then every time it wakes up it runs your "dowork" and then at the end of the dowork you work out when you want it to run next, set the interval as appropriate and then call Start on your timer again.
Of course in your service your start method just sets up the first timer run and then returns so that the startup is nice and quick. On shutdown you just clean up your timer (stop and dispose and such like) and then just return. Nice and clean.
I think you might be looking for something like this:
static class ConsoleProgram
{
static void Main()
{
ServiceBase[] servicesToRun = new ServiceBase[] { new MyService(config, Logger) };
ServiceBase.Run(servicesToRun);
}
}
public partial class MyService : ServiceBase
{
private bool _stopped = true;
protected override void OnStart(string[] args)
{
StartTimer();
}
protected override void OnStop()
{
StopTimer();
}
public void StartTimer()
{
_stopped = false;
Timer t = new Timer(TimerProc);
// Calculate your desired interval here.
t.Change(_config.Interval, new TimeSpan(0, 0, 0, 0, -1));
}
public void StopTimer()
{
_stopped = true;
}
private void TimerProc(object state)
{
// The state object is the Timer object.
Timer t = (Timer) state;
t.Dispose();
ThreadPool.QueueUserWorkItem(DoWork);
if (!_stopped) {
StartTimer();
}
}
}

System.Timers.Timer delay hangs application

I have an issue with the System.Timers.Timer object. I use the timer object to perform a task at regular intervals. In the timer constructor I call the method doing the work ( DoTimeCheck() ), to ensure that the task is run once at startup also. The work (at regular intervals) is done in a BackgroundWorker.
I call the timer with this:
UpdaterTimer ut = UpdaterTimer.UpdaterTimerInstance;
My problem is that I need to delay the first run of the task with 3 minutes(the one that runs at application startup). Subsequent runs (Elapsed event) should run without delay. I thought of doing this by calling
System.Threading.Thread.Sleep(TimeToDelayFirstRunInMiliseconds);
but this fails, because it also hangs the UI of the app (main thread) making it unusable. How can I delay the first run of DoTimeCheck() without hanging the UI?
The code of the timer is below. If the issue is not presented in a clear manner please let me know and I will edit. Thank you in advance.
public sealed class UpdaterTimer : Timer
{
private static readonly UpdaterTimer _timer = new UpdaterTimer();
public static UpdaterTimer UpdaterTimerInstance
{
get { return _timer; }
}
static UpdaterTimer()
{
_timer.AutoReset = true;
_timer.Interval = Utils.TimeBetweenChecksInMiliseconds;
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Start();
DoTimeCheck();
}
static void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
DoTimeCheck();
}
private static void DoTimeCheck()
{
//... work here
}
}
One way of doing this would be to give the Timer Interval an initial value (e.g. 3 minutes). Then, in your Elapsed event handler, you could change the interval to your regular value which will be used from then on.
_timer.Interval = Utils.InitialCheckInterval;
static void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
if (_timer.Interval == Utils.InitialCheckInterval)
{
_timer.Interval = Utils.RegularCheckInterval;
}
DoTimeCheck();
}
It appears (although you've not shown that code) that you're calling Sleep(TimeToDelayFirstRunInMiliseconds); on the main/GUI thread, so that's what's causing your UI thread to hang. Instead, you should set your timer to be delayed by 3 minutes on the first run, then once it runs you change the timer again to run at the frequency you desire for all the subsequent runs.
Your UI resides on the same thread, so when you put the thread to sleep, it will cause your UI to hang as well. You need to run the timer on a different thread.
You're already using timers fine it seems. Just use another one to do a three minute delay before you start up your other timer.
timer = new Timer();
timer.AutoReset = false;
timer.Interval = 3*60*1000;
timer.Elapsed += startOtherTimerMethod;
timer.Start();
Edit: I should note that this is much the same as Peter Kelly's answer except that his solution is more elegant since it uses just one timer, no extra methods and takes advantage of the fact that the timer is changeable between runs. If you liked this answer, you'll love his. ;-)
Your UI needs a seperate thread, currently you are also sleeping the UI. Check this post.
You should not use thread.sleep in this situation you should use the winforms control
BackgroundWorker which never locks the main UI. You can write your logic there.
example here:
http://www.knowdotnet.com/articles/backgroundworker.html
Use a System.Threading.Timer - the constructor takes a parameter for the delay of the first run and an interval for the subsequent runs.

Categories