Is my Timer causing my application to hang? - c#

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.

Related

System.Threading.Timer does not work correctly

I notice the timer is not correct.
This is a very simple C# code: it will print current date/time every 1 minute.
My expected result is: let it run at 3:30 PM then we will have: 3:31 PM, 3:32 PM, 3:33 PM, ...
But sometime don't receive above result: sometime it is 3:31 PM, 3:32 PM, 3:34 PM, ...
So it lost 1 row.
Could anyone point me what is problem?
class Program
{
static Timer m_Timer;
static int countDown;
static void Main(string[] args)
{
countDown = 60;
m_Timer = new Timer(TimerCallback, null, 0, 1000);
while (true) { System.Threading.Thread.Sleep(10); };
}
static void TimerCallback(Object o)
{
countDown -= 1;
if (countDown <= 0)
{
Console.WriteLine(" ===>>>>>" + System.DateTime.Now.ToString());
countDown = 60;
}
System.Threading.Thread.Sleep(10000); //long running code demo
}
}
System.Threading.Timer runs on threads from thread pool. You run callback function which runs on one thread in pool every 1s and block it for 10s using sleep. Depending on how many threads you have in thread pool at some timepoints they all may be blocked and wait or .NET should allocate new thread up to the maximum of threads in pool for you.
From comments extended answer.
Each function is independent and it does not wait until another processing finish. A simple task is: call a function to do something every 1 minutes. "do something" in my case is saving local variables into SQL server. This process is fast not slow. I use 1 timer for many functions because each function is schedule in different cycle. For example, function 1 is triggered every 1 minute, function 2 is triggered every 10 seconds ... That why I use the timer 1 second.
Your use case seems to be more complex as I read it from initial question. You have different tasks and try to implement sort of scheduler. Maybe each particular tasks is fast but all together some runs may be longer and blocking. Not sure how this logic was well implemented but there could be a lot of edge cases e.g. some run was missed etc.
How I would approach it?
I would not try to implement on my own if scheduler can be more complex. I would pick ready solution, e.g. Quartz.NET. They consider edge cases and help to scale on cluster with needed and help with config.
In any case I would refactor bigger schedule to have each task to run on its schedule based on configuration (custom implementation or Quartz) as smaller tasks
I would scale your "queue" of tasks first locally by introducing some queue, for example using ConcurrentQueue or BlockingCollection or any produce-consumer to limit number of threads and if performance of such execution is not good scale on cluster. By doing so you can at least guarantee that N tasks can be scheduled and executed locally and everything beyond is queued. Maybe having some priorities for tasks can also help because there might be execution which could be missed but there are execution which must run on schedule.
I doubt it is a good idea to start from thread timer execution other threads or tasks if most likely you already have problems with threading.
You problem is not with System.Threading.Timer, it does its job well. Your use case is more complex.
Windows - is not real time operating system. So, if you expect that timer waits ecactly 1 second - it's wrong. There are many reasonsm when timer can wait more time. Because of timer resolution or other high load operations.
If you like newer .NET TPL syntax yo can write it like this:
using System;
using System.Threading.Tasks;
namespace ConsoleApp1
{
internal class Program
{
private static void Main(string[] args)
{
Repeat(TimeSpan.FromSeconds(10));
Console.ReadKey();
}
private static void Repeat(TimeSpan period)
{
Task.Delay(period)
.ContinueWith(
t =>
{
//Do your staff here
Console.WriteLine($"Time:{DateTime.Now}");
Repeat(period);
});
}
}
}
The above code causes, that every second you run 10-second "demo" (sleep). You will run 10 worker threads simultanously.
Are you sure, this is what you are trying to achieve?
To see what really happens in your app, simply add:
Console.WriteLine($"Time:{DateTime.Now.ToString("hh:mm:ss.fff tt")},Thread:{Thread.CurrentThread.ManagedThreadId},countDown:{countDown}");
in the beginning of TimerCallback. You will notice, that timespan between following callbacks are not exactly 1000ms (usually it is a little bit more). This is perfectly normal in non-rtc OS, and, in most cases - it's not a problem. Just keep in mind, that Timer is not exact.
Moreover, if you are trying to use Timer that way, and trying to count ticks - these little errors cumulates in following ticks.
I just post what found here for people that have problem like me.
I found the answer from another thread.
I use "HighResolutionTimer.cs" and it works perfect:
https://gist.github.com/DraTeots/436019368d32007284f8a12f1ba0f545

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.

Thread.Sleep - how to use it in a proper way?

System.Threading.thread.Sleep(1000); pauses a whole program for 1 second, but when this second is over it does everything what could be done for this period. For example:
Thread.Sleep(1000);
Console.WriteLine("A");
Thread.Sleep(1000);
Console.Writeline("B");
It will wait two seconds and write
A
B
How to use the pause properly?
If you want something to happen once per second, then create a timer. For example:
private System.Threading.Timer _timer;
void main()
{
_timer = new Timer(TimerTick, null, 1000, 1000);
// do other stuff in your main thread
}
void TimerTick(object state)
{
// do stuff here
}
There are several different types of timers. If you're writing a console program, then I would suggest using System.Threading.Timer. In a Windows Forms application, either System.Windows.Forms.Timer or System.Timers.Timer. See Timers for more information.
Thread.Sleep() behaves just like you would think; it just pauses the current thread for approximately the given number of milliseconds.
The problem here is that the standard output stream does not necessarily flush to the console (or wherever it is pointed at) to on each call to Write. Instead, it may buffer some content so as to write it out in larger chunks for efficiency. Try calling Console.Out.Flush(); after each WriteLine() and you should see the results you expect.

how to set timer for each different thread in window service

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.

How to wait for a period of time or function call, whichever takes longest even when the system time changes?

I have a situation where I don't want to be executing a particular function too quickly. I currently have this code:
DoSomething();
Thread.Sleep(TimeSpan.FromMilliseconds(200));
How can I change this code to run for the max of the function time or the wait time?
Please note: I can't use the system time because my software can change the clock time.
So, if DoSomething() takes 400 MS, it would only wait 400 MS, but if it took 100 MS, the program would wait 200 MS.
Maybe something like this:
var stopWatch = new StopWatch();
stopWatch.Start();
DoSomething();
stopWatch.Stop();
var diff = 200 - stopWatch.Elapsed.TotalMilliseconds;
if(diff > 0)
Thread.Sleep(diff);
The StopWatch class is not using the system clock for its measurement:
The Stopwatch measures elapsed time by counting timer ticks in the underlying timer mechanism. If the installed hardware and operating system support a high-resolution performance counter, then the Stopwatch class uses that counter to measure elapsed time. Otherwise, the Stopwatch class uses the system timer to measure elapsed time.
Update:
You write:
So, if DoSomething() takes 400 MS, it would only wait 400 MS, but if it took 100 MS, the program would wait 200 MS.
I first thought, this was not what you wanted, because, in the second case, it takes a total time of 300 MS. But if that indeed is, what you want, take this code:
var stopWatch = new StopWatch();
stopWatch.Start();
DoSomething();
stopWatch.Stop();
var timeToSleep = 200;
if(stopWatch.Elapsed.TotalMilliseconds < timeToSleep)
Thread.Sleep(timeToSleep);
IF can use the V4 of .Net, create two tasks and wait for both ended.
Something like this :
Task.WaitAll(
Task.Factory.StartNew(()=>DoSomething()),
Task.Factory.StartNew(()=>Thread.Sleep(200))
);
You could time the duration of DoSomething with a Stopwatch and wait the difference between your target time and the duration of the method call or nothing if the method call exceeds your wait time.
You could make two threads, one that does the actual work, and a second thread that sleeps for a given time. Then you use Thread.Join() in the main thread to wait for the two threads to end.
// Define the threads and there startpoint
Thread thread1 = new Thread(DoSomething);
Thread thread2 = new Thread(() => Thread.Sleep(2000));
// Start both threads
thread1.Start();
thread2.Start();
// Wait for both threads to be finished.
thread1.Join();
thread2.Join();

Categories