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

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.

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.

Scheduled operations in C# with option to FullStop immediately

I need to do some operations on a certain interval (e.g. from 5 to 5 minutes in a loop) but need to be able to fully stop the thing whenever I want (on push of a button).
I was thinking into using a Timer class but events might fire even after the timer is stopped.
How can I have some code running on a timer and still be able to immediately bring everything to a complete stop?
Just so I am properly understood: By complete stop I mean that events stop and I can dispose of objects like the timer itself etc. I am not asking how to avoid having side effects from unexpected events that are fired after the timer is stopped!
Answer to this question depends a lot on a type of your operations.
Best scenario is to run a thread with a loop and listen to abort event.
static AutoResetEvent abort = new AutoResetEvent();
Thread worker = new Thread(WorkerThread);
void MainThread()
{
worker.Start();
Thread.Sleep(30000);
abort.Set();
}
void WorkerThread()
{
while(true)
{
if(abort.WaitOne(5000)) return;
// DO YOUR JOB
}
}
When you call abort.Set() from another thread, this one will exit.
But if your code is long running, you won't be able to exit until job is done.
To exit immediately you will have to abort thread, but this is not too wise because of resource consumption.
Alternatively, if your operation is long running (let's say you are going through long array), you can check "abort" event state from time to time (every iteration of loop, for example) like this abort.WaitOne(0).
The race condition with the timer is unavoidable since, as you say, the callbacks are executed from the thread pool. However, I believe you can safely dispose the timer even while it's still executing the events. An option which might help is if you consider using the System.Threading.Timer instead of System.Timers.Timer, for which you can call Timer.Dispose(WaitHandle) if you need to have a way to know when the timer events have finished executing. This will prevent race conditions for the cases where you also need to dispose of some other resource - a resource that the event consumer function will attempt to use.
As for the "immediate" requirement, the most immediate would probably be something that uses a synchronization primitive of sorts to stop execution. For example consider this:
static System.Timers.Timer timer;
static void Main(string[] args)
{
var cancelSource = new CancellationTokenSource();
timer = new System.Timers.Timer(200);
timer.Elapsed += new SomeTimerConsumer(cancelSource.Token).timer_Elapsed;
timer.Start();
// Let it run for a while
Thread.Sleep(5000);
// Stop "immediately"
cancelSource.Cancel(); // Tell running events to finish ASAP
lock (timer)
timer.Dispose();
}
class SomeTimerConsumer
{
private CancellationToken cancelTimer;
public SomeTimerConsumer(CancellationToken cancelTimer)
{
this.cancelTimer = cancelTimer;
}
public void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
lock (timer)
{
// Do some potentially long operation, that respects cancellation requests
if (cancelTimer.IsCancellationRequested)
return;
// More stuff here
}
}
}
This is a toy example, but it illustrates my point. The 3 lines that do the "stop immediately" have the following features:
By the time the Dispose call returns, none of the // More stuff here code will ever execute again.
None of the // More stuff here code can execute while the timer is being disposed, because of the lock.
The previous 2 features require the lock, but they prevent the timer from stopping "immediately" because on entering the lock it needs to wait for all timer events calls to finish if they have started. For this reason I added in the cancellation as the fastest way to abort the currently executing events while still guaranteeing that they won't be executing during timer dispose.
Note: if you need multiple timer events to execute simultaneously, consider using a ReaderWriterLockSlim instead of a monitor.
I'd consider one of these two options:
Put a safety check in the events that you need to execute. Something like a database flag. So even if the Timer fails to stop the event will bail out when the safety check fails.
Use something like Quartz.Net for scheduling. This is really heavy handed but it'll do what you want.

Windows service scheduled execution

If I have a Windows Service that needs to execute a task every 30 seconds which is better to use; the Timer() class or a loop that executes the task then sleeps for a number of seconds?
class MessageReceiver
{
public MessageReceiver()
{
}
public void CommencePolling()
{
while (true)
{
try
{
this.ExecuteTask();
System.Threading.Thread.Sleep(30000);
}
catch (Exception)
{
// log the exception
}
}
}
public void ExecutedTask()
{
// do stuff
}
}
class MessageReceiver
{
public MessageReceiver()
{
}
public void CommencePolling()
{
var timer = new Timer()
{
AutoReset = true,
Interval = 30000,
Enabled = true
};
timer.Elapsed += Timer_Tick;
}
public void Timer_Tick(object sender, ElapsedEventArgs args)
{
try
{
// do stuff
}
catch (Exception)
{
// log the exception
}
}
}
The windows service will create an instance of the MessageReciever class and execute the CommencePolling method on a new thread.
I think it really depends on your requirement.
case 1.
Suppose you want to run this.ExecuteTask() every five minutes starting from 12:00AM (i.e., 12:00, 12:05, ...) and suppose the execution time of this.ExecuteTask() varies (for example, from 30 sec to 2 min), maybe using timer instead of Thread.Sleep() seems to be an easier way of doing it (at least for me).
However, you can achieve this behavior with Thread.Sleep() as well by calculating the offset while taking timestamps on a thread wake-up and on a completion of this.ExecuteTask().
case 2.
Suppose you want to perform the task in the next 5 min just after completion of this.ExecuteTask(), using Thread.Sleep() seems to be easier. Again, you can achieve this behavior with a timer as well by reseting the timer every time while calculating offsets on every time this.ExecuteTask() completes.
Note1, for the case 1, you should be very careful in the following scenario: what if this.ExecuteTask() sometimes takes more than the period (i.e. it starts at 12:05 and completes 12:13 in the example above).
What does this mean to your application and how will it be handled?
a. Total failure - abort the service or abort the current(12:05) execution at 12:10 and launch 12:10 execution.
b. Not a big deal (skip 12:10 one and run this.ExecuteTask() at 12:15).
c. Not a big deal, but need to launch 12:10 execution immediately after 12:05 task finishes (what if it keeps taking more than 5 min??).
d. Need to launch 12:10 execution even though 12:05 execution is currently running.
e. anything else?
For the policy you select above, does your choice of implementation (either timer or Thread.Sleep()) easy to support your policy?
Note2. There are several timers you can use in .NET. Please see the following document (even though it's bit aged, but it seems to be a good start): Comparing the Timer Classes in the .NET Framework Class Library
Are you doing anything else during that ten second wait? Using Thread.sleep would block, preventing you from doing other things. From a performance point of view I don't think you'd see too much difference, but I would avoid using Thread.sleep myself.
There are three timers to choose from - System.Windows.Forms.Timer is implemented on the main thread whereas System.Timers.Timer and System.Threading.Timer are creating seperate threads.
I believe both methods are equivalent. There will be a thread either way: either because you create one, or because the library implementing the Timer class creates one.
Using the Timer class might be slightly more less expensive resource-wise, since the thread implementing timers probably monitors other timeouts as well.
I this the answers to this question will help.
Not answered by me but John Saunders (above)... the answer can be found here For a windows service, which is better, a wait-spin or a timer?

Creating a Loop to Pause a Script While a Callback Function Operates

I am currently using a third party component to handle telnet connections in .NET. I want it to be synchronous where I send a command to the receiving telnet server and then I get the response back as text or byte array. Only problem is that the component is not set up to do that. The component allows me to send commands to the server, but the response is returned via a function handle. So in essence, I need a way to pause the application while the handler does it's processing. Here is an example of how I plan to get around that issue:
static void Main(string[] args)
{
Telnet telCon = new Telnet();
telCon.OnDataIn += new Telnet.OnDataInHandler(HandleDataIn);
telCon.Connect(remoteHostStr);
while (true) ;
}
public static void HandleDataIn(object sender, TelnetDataInEventArgs e)
{
string responseStr = e.Text;
if (responseStr.Contains("Username:"))
{
((Telnet)sender).Send(System.Text.ASCIIEncoding.ASCII.GetBytes(username));
}
else if (responseStr.Contains("Password:"))
{
((Telnet)sender).Send(System.Text.ASCIIEncoding.ASCII.GetBytes(password));
}
}
The solution above will not work since the while will always run, but I will probably build a future version that uses some sort of global variable to track if the loop still needs to run. However, everything I have been taught about programming says this is very dirty. Can anyone think of another way around my dilemma?
Thanks,
Chris
Here is an example of using a ManualResetEvent to suspend execution (and delay program end) until your event handler says it's finished.
static ManualResetEvent finishGate;
static void Main(string[] args)
{
finishGate = new ManualResetEvent(false); // initial state unsignaled
Telnet telCon = new Telnet();
telCon.OnDataIn += new Telnet.OnDataInHandler(HandleDataIn);
telCon.Connect(remoteHostStr);
finishGate.WaitOne(); // waits until the gate is signaled
}
public static void HandleDataIn(object sender, TelnetDataInEventArgs e)
{
// handle event
if (processingComplete)
finishGate.Set(); // signals the gate
}
The WaitOne() method of ManualResetEvent also includes overrides that accept a timespan or number of milliseconds. It returns bool - true if it was signaled, false if it timed out. If you put that in a loop, you could have your main thread wake up every 30 seconds and perform some housekeeping tasks, but still have an instantaneous response when the gate is signaled.
Your while loop:
while(true) ;
will drive CPU usage to 100% (well, 100% of 1 core on a multicore machine) and leave it there, permanently.
This will starve other processes of CPU power, and may prevent the Telnet component from working at all because you've bypassed the message pump.
There are better ways, but without more information on what you're doing, it will be hard to advise you.
To begin, do you want a WindowsForms/WPF/Console application?
[And please, use comments to answer, not Answers.]
In general, when you really need to wait, use a WaitHandle. In this case, a ManualResetEvent would probably be what you need.
A better way would be to spawn the Telnet processing to another thread. That way you can get the main thread to wait for the telnet processing to complete.
Have a look here for some very good tutorials on threading.

Categories