Does usage of Thread.Sleep(n) causes performance issues? - c#

I am using Thread.Sleep(n) for my project. I heard that Thread.Sleep can cause performance issues but not sure about it.
My requirement is:
Wait for 5 minute increments, up to 30 minutes (6 times the 5 minute
delay). After this, begin to increment by 1 hour and do this 5 times
(additional 5 hours).
Below I have provided my sample code which uses Thread.Sleep(n) in different scenarios:
Thread.Sleep(1000 * 60 * 5); //-------waiting for 5 minutes
var isDownloaded = false;
try
{
var attempt = 0;
while (attempt < 11)
{
isDownloaded = TryDownloading(strPathToDownload, strFileToDownload);
if (isDownloaded)
break;
attempt++;
if (attempt < 6)
Thread.Sleep(1000 * 60 * 5); //--------waiting for 5 minutes
else
{
if (attempt < 11)
Thread.Sleep(1000 * 60 * 60); //-------waiting for 1 hour
else
break;
}
}
}
On the above code I am trying to download a file with a maximum of 11 download attempts. Initially it waits for 5 minutes and then try to download the file which is the first attempt and if failed then it tries for the next 5 attempts with an interval of 5 minutes each. If they failed for the first six attempts then it go for the next 5 attempts with an interval for 1 hour each.
So we decided to use Thread.Sleep for those time delay in our console app.
Does this causes any problem or performance issues?
If Thread.Sleep(n) causes performance issues, then which would be an better alternative way instead of using Thread.Sleep(n)?
Also finally, Does MSDN suggested that Thread.Sleep(n) is harmful or it shouldn't be used?

This is absolutely fine. Here are the costs of sleeping:
You keep a thread occupied. This takes a little memory.
Setting up the wait inside of the OS. That is O(1). The duration of the sleep does not matter. It is a small, constant cost.
That's all.
What is bad, though, is busy waiting or doing polling loops because that causes actual CPU usage. Just spending time in a sleep or wait does not create CPU usage.
TL;DR: Use sleep for delays, do not use sleep for polling.
I must say that the aversion against sleeping is sometimes just a trained reflex. Be sure to analyze the concrete use case before you condemn sleeping.

Do not use ASP.NET worker process to run long running tasks!
The app pool may be recycled any time and you will lose your sleeping threads.
Consider using Windows Service instead.
You can communicate between web site and windows service using database or messaging.

You'd better use a Timer to perform intermittent action like that because Thread.Sleep is a blocking call and keeps the process allocated and the application freeze.
like this:
in the caller object
Timer t = new Timer(1000 * 60 * 5);
t.Tick += t_Tick;
t.Start();
than implement the event
//event timer elapsed implementation
int count = 0;
private void t_Tick(object sender, EventArgs e)
{
if(count >=5)
t.Stop();
else{
//your code that do the work here
}

Related

System.Timers.Timer not firing at the interval set

I am working in timer from System.Timers namespace in wpf application.I want some backend behaviour to execute with timers and call in n milliseconds.
Timer sampleTimer = new Timer();
sampleTimer.Elapsed += (sender, e) => CallElapsedEvent();
sampleTimer.Interval = 10000; //called every 10 seconds
sampleTimer.Enabled = true;
public void CallElapsedEvent(){
Console.WriteLine(DateTime.Now + " - CallElapsedEvent called");
}
Here is the output of the code
16:45:09 - CallElapsedEvent called
16:45:32 - CallElapsedEvent called
16:45:32 - CallElapsedEvent called
Expected behaviour is that after 9th second , it must fire again at 19.But it is called after an interval of 23 seconds and that too twice(at exactly the same sec).This is happening occassionally and causes some unexpected exception.Why is that happening so?
From what I read about ,it allocates thread pool thread every n interval seconds.If elapsed event is not finished it allocates some other new thread.So, in my case is there are no other free worker threads available at 19th second and waits for the thread.
Why is that happening so and is there any way to enter only one thread to fire at a time?

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

Threading and timers inside an emulator

I'm developing a Chip-8 emulator in C#, I have completed partially almost every aspect but there is something I'm still wondering about speed control of the emulator.
What I'm doing now is assuming that I get 60 frames per second, I use a timer that fires 1/60 seconds in the following manner (pseudocode):
timer_ticked()
{
for(int i = 0; i < Settings.CyclesPerFrame; i++)
{
EmulateCycle();
}
if (IsDrawFlagSet)
{
DrawGraphics();
}
}
I'm using a high resolution timer called microtimer http://www.codeproject.com/Articles/98346/Microsecond-and-Millisecond-NET-Timer , I believe that the timer doesn't wait for timer_ticked to finish to fire the next cycle (fon instance, creating a new thread) and I'm having an issue with threads and the form since trying to paint to a window with GDI (using the control.GetGraphics() method) seems to be threadsafe, but trying to create an SDLDotNet approach (just an example) doesnt.
Which approach do you think is best to control the speed of an emulator without getting into timer thread insanity?
PS: You can find the source code of the emulator in GitHub: https://github.com/AlFranco/C8POC
Thank you!
If you tick method is being called again before it's done, the problem isn't with your timer. It's because the processing is taking longer than that 16.6 ms. Getting a better timer isn't going to solve your problem.
That said, you can prevent reentrancy in a couple of ways.
You could just disable the timer when you enter the callback, and re-enable it when you're done. That'll prevent multiple invocations:
timer_ticked()
{
timer.Enabled = false;
// do stuff here
timer.Enabled = true;
}
Note that this doesn't give you a perfect 16.6 ms tick frequency. Rather, the next tick will occur 16.6 ms (approximately) after you enable the timer. Your real period is 16.6 ms plus however long it takes to do the processing.
The only time this would fail is if the timer_ticked method wasn't called before the next tick happened.
If you want to guarantee that you can't get concurrent ticks, you can use a System.Threading.Timer and set it up as a one-shot (no periodic signaling). For example:
Timer myTimer = new Timer(timer_tick, null, 16, -1);
The -1 in the last parameter tells it not to be a periodic timer. It'll fire once and stop.
Then, in your timer tick:
timer_tick()
{
// do stuff
// restart the timer
myTimer.Change(16, -1);
}
Edit
You can't easily tell the timer not to issue a tick if the handler is still processing the previous tick. You can, however, prevent the timer tick handler from doing anything on that subsequent tick. You simply use a Monitor:
private object timerLock = new object();
timer_ticked()
{
if (!Monitor.TryEnter(timerLock))
return;
try
{
// do stuff here
}
finally
{
Monitor.Exit(timerLock);
}
}
The problem with such a solution is that if your timer is set of 16 ms and the handler takes 17 ms, then your effective update rate will be once every 32 ms, because the second tick is essentially ignored. You're better off with the one-shot timer deal.
Another possibility is to use a Stopwatch to time how long your handler takes, and subtract that from the next delay period:
timer_ticked()
{
var sw = Stopwatch.StartNew();
// do stuff
timer.Change(16-sw.ElapsedMilliseconds, -1);
}
But it's not quite that simple. If it takes longer than 16 ms for the handler to do its thing, you'll end up with a negative delay. So you'll want:
var delayTime = Math.Max(0, 16 - sw.ElapsedMilliseconds);
timer.Change(delayTime, -1);
But again, if your handler regularly takes longer than the timer delay, then this isn't going to help you. You'll either have to reduce your timer frequency (i.e. make a longer delay) or optimize your processing code.

Why Thread.Sleep() is so CPU intensive?

I have an ASP.NET page with this pseduo code:
while (read)
{
Response.OutputStream.Write(buffer, 0, buffer.Length);
Response.Flush();
}
Any client who requests this page will start to download a binary file. Everything is OK at this point but clients had no limit in download speed so changed the above code to this:
while (read)
{
Response.OutputStream.Write(buffer, 0, buffer.Length);
Response.Flush();
Thread.Sleep(500);
}
Speed problem is solved now, but under test with 100 concurrent clients who connect one after another (3 seconds lag between each new connection) the CPU usage increases when the number of clients increases and when there are 70 ~ 80 concurrent clients CPU reaches 100% and any new connection is refused. Numbers may be different on other machines but the question is why Thread.Sleep() is so CPU intensive and is there any way to speed done the client without CPU rising ?
I can do it at IIS level but I need more control from inside of my application.
Let's take a look at whether Michael's answer seems reasonable.
Now, Michael wisely points out that Thread.Sleep(500) shouldn't cost much in the way of CPU. That's all well and good in theory, but let's see if that pans out in practice.
static void Main(string[] args) {
for(int i = 0; i != 10000; ++i)
{
Thread.Sleep(500);
}
}
Running this, the CPU use of the application hovers around the 0% mark.
Michael also points out that since all the threads that ASP.NET has to use are sleeping, it will have to spawn new threads, and offers that this is expensive. Let's try not sleeping, but doing lots of spawning:
static void Main(string[] args) {
for(int i = 0; i != 10000; ++i)
{
new Thread(o => {}).Start();
}
}
We create lots of threads, but they just execute a null operation. That uses a lot of CPU, even though the threads aren't doing anything.
The total number of threads never gets very high though, because each lives for such a short time. Lets combine the two:
static void Main(string[] args) {
for(int i = 0; i != 10000; ++i)
{
new Thread(o => {Thread.Sleep(500);}).Start();
}
}
Adding this operation that we have shown to be low in CPU use to each thread increases CPU use even more, as the threads mount up. If I run it in a debugger it pushes up to near 100% CPU. If I run it outside of a debugger, it performs a bit better, but only because it throws an out of memory exception before it gets a chance to hit 100%.
So, it isn't Thread.Sleep itself that is the problem, but the side-effect that having all available threads sleep forces more and more threads to be created to handle other work, just as Michael said.
Just a guess:
I don't think it's Thread.Sleep() that's tying up the CPU - it's the fact that you're causing threads to be tied up responding to a request for so long, and the system needs to spin up new threads (and other resources) to respond to new requests since those sleeping threads are no longer available in the thread pool.
Rather than an ASP.NET page you should implement an IHttpAsyncHandler. ASP.NET page code puts many things between your code and the browser that would not be appropriate for transferring binary files. Also, since you're attempting to perform rate limitation, you should use asynchronous code to limit resource usage, which would be difficult in an ASP.NET page.
Creating an IHttpAsyncHandler is fairly simple. Just trigger some asynchronous operations in the BeginProcessRequest method, and don't forget to properly close the context to show you have reached the end of the file. IIS won't be able to close it for you here.
The following is my really bad example of how to perform an an asynchronous operation consisting of a series of steps, counting from 0 to 10, each performed at a 500ms interval.
using System;
using System.Threading;
namespace ConsoleApplication1 {
class Program {
static void Main() {
// Create IO instances
EventWaitHandle WaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset); // We don't actually fire this event, just need a ref
EventWaitHandle StopWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
int Counter = 0;
WaitOrTimerCallback AsyncIOMethod = (s, t) => { };
AsyncIOMethod = (s, t) => {
// Handle IO step
Counter++;
Console.WriteLine(Counter);
if (Counter >= 10)
// Counter has reaced 10 so we stop
StopWaitHandle.Set();
else
// Register the next step in the thread pool
ThreadPool.RegisterWaitForSingleObject(WaitHandle, AsyncIOMethod, null, 500, true);
};
// Do initial IO
Console.WriteLine(Counter);
// Register the first step in the thread pool
ThreadPool.RegisterWaitForSingleObject(WaitHandle, AsyncIOMethod, null, 500, true);
// We force the main thread to wait here so that the demo doesn't close instantly
StopWaitHandle.WaitOne();
}
}
}
You'll also need to register your IHttpAsyncHandler implementation with IIS in whichever way is appropriate for your situation.
Its because the thread gets a priority boost every time it yields its time slice. Avoid calling sleep often ( particularly with low values ).

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?

Categories