sleep-until in c# - c#

I want to run a function periodically every 1 second, so after 10 seconds it is executed 10 times.
The simplest approach is using a loop like this :
while(true)
{
Thread.Sleep(1000);
function();
}
But the main problem with this approach is that it will not provide any periodic guarantees.
I mean if it takes 0.1 seconds to run function() the executions time of the function will be like this :
0, 1.1 , 2.2, 3.3, 4.4 , ...
As I remember, in real time language ADA we have a function sleep-until(#time). Now I'm looking for an alternative in C#.
Any sample code will be appreicated.

System.Threading.Timer timer = new System.Threading.Timer(ThreadFunc, null, 0, 1000);
private static void ThreadFunc(object state)
{
//Do work in here.
}
See MSDN for more info.

You can use Stopwatch to measure the time. I would also use a For-Loop instead.
var sw = new System.Diagnostics.Stopwatch();
var timeForOne = TimeSpan.FromSeconds(1);
var count = 10;
for(int i = 0; i < count; i++)
{
sw.Restart();
function();
sw.Stop();
int rest = (timeForOne - sw.Elapsed).Milliseconds;
if (rest > 0)
System.Threading.Thread.Sleep(rest);
}

To invoke something after specific interval of time you should use Timer class.
Here is the Tutorial

Related

Execute action every x milliseconds in while loop [duplicate]

This question already has answers here:
How do you add a timer to a C# console application
(12 answers)
Closed 5 years ago.
I have a while loop that runs for a long number of times. I have some writelines in there that serve as debug statements. I use a verbosity flag to determine when I want to see those statements written to the console. Is there a way I can also specify to output every x milliseconds , instead of all the time.
while
{
//logic here
if(verboseMode)
Console.Writeline("some status message")
}
With the way the code is right now, the writeline executes all the time when verboseMode is set to true. What id like to do is output the line if verboseMode is set to true and the last time I output something it was x milliseconds ago
You can use a Timer or just keep track of when you last wrote output. The Timer is probably preferable because your main functionality won't block it from running whereas the other will.
I used random just to simulate the fact that the while loop won't always run in the same amount of time to demonstrate the difference between the approaches.
var r = new Random();
var t = new System.Timers.Timer() { Interval = 1500 };
t.Elapsed += (s, e) =>
Console.WriteLine(DateTime.Now.TimeOfDay);
t.Start();
while (true)
{
Thread.Sleep(r.Next(500, 1000));
Console.WriteLine("doing stuff");
}
var r = new Random();
var prev = DateTime.Now;
var interval = 1500;
while (true)
{
Thread.Sleep(r.Next(500, 1000));
Console.WriteLine("doing stuff");
var now = DateTime.Now;
if (prev.AddMilliseconds(interval) >= now)
{
prev = DateTime.Now;
Console.WriteLine(DateTime.Now.TimeOfDay);
}
}
What you ask for is rate limiting. I wrote this code originally for Multithreading, but it should get you the idea:
integer interval = 20;
DateTime dueTime = DateTime.Now.AddMillisconds(interval);
while(true){
if(DateTime.Now >= dueTime){
//insert code here
//Update next dueTime
dueTime = DateTime.Now.AddMillisconds(interval);
}
else{
//Just yield to not tax out the CPU
Thread.Sleep(1);
}
}
Note that DateTime is not nearly as accurate as the type is precise. Often the smalest difference tracked is 16 ms or so. But then again, 16 ms would get you around 60 changes per seconds, wich is propably to top adivseable writing/updating speed anyway.
If you don't care much about precision you can get away with running the while loop on a different thread using Task.Run:
var source = new CancellationTokenSource();
var task = Task.Run(() =>
{
while (!source.Token.IsCancellationRequested)
{
DoSomething();
await Task.Delay(500, source.Token);
}
});
// If you want to cancel the loop
source.Cancel();
task.Wait(); // or 'await task;' if you're in an async method

Calculate code run time/speed

I am very curious about run time/speed about codes in ms visual studio.
As instance,
1. code:
byte[] buffer = new byte[4096];
var p = System.IO.Directory.GetFiles(directoryName);
2. code
var entry = new ZipEntry(Path.GetFileName(file));
entry.DateTime = DateTime.Now;
If i run 1. code ı want to see "it's running time/speed 0.03 seconds"
If i run 2. code ı want to see "it's running time/speed 0.06 seconds"
Is there anything to calculate running time/speed of codes in c# without using timer ?
Any help will be appreciated.
Thanks.
The best thing to use for quickly profiling code is Stopwatch in System.Diagonstics
var sw = Stopwatch.StartNew();
///.... stuff
sw.Stop();
sw.ElapsedMilliseconds;
If this is something you may want to use in production, i'd recommend: http://miniprofiler.com/
You can use a Stopwatch for benchmarking code
var sw = Stopwatch.StartNew();
var entry = new ZipEntry(Path.GetFileName(file));
sw.Stop();
Console.WriteLine("Time to zip: {0}", sw.Elapsed);
You could create a helper method if you intend on doing using it a lot
public static TimeSpan Benchmark(Action action)
{
var sw = Stopwatch.StartNew();
action();
sw.Stop();
return sw.Elapsed;
}
...
var timeTaken = Benchmark(() => /* run some code */)
Typically one would use the stopwatch.startnew, stop, elapsedtime methods.
There are some profiling tools on the market, and microsoft also has its own built-in performance suite. The following link is a tutorial on how to set it up.
http://msdn.microsoft.com/en-us/library/ms182372.aspx

Slow initialization of multiple system.threading.timer

I have a program which check goods status of a website.
As I hadnt learn threading before, I simply use system.threading.timer in my program.
I have a List of system.threading.timer and a few system.threading.timer
List<system.threading.timer> _timerList;
System.threading.timer _timerA;
System.threading.timer _timerB;
System.threading.timer _timerC;
I called _timerA to check goods status and called _timerList to buy the goods with a account list of 10 accounts when the goods is up.
I execute _timerA per 500 ms.
_timerA = new System.Threading.Timer(new TimerCallback(submit_checkgoods), 0, 0, 500);
Inside submit_checkgoods ( _timerList.Add(...) is called earlier ):
if ( goodsIsUp == true)
{
for (int k = 0; k < infolistbb.Count; k++)
{
int copy = k;
_timerList[copy] = new System.Threading.Timer(new TimerCallback(submit_buygoods), copy, 0, 0);
}
}
The problem is that I find that calling _timerlist[copy] to execute is very slow.
I used stopwatch to check the time of calling _timerlist to execute to the end of submit_buygoods and the time of executing submit_buygoods.
The exection of submit_buygoods is really quick but the calling process is like one by one.
After _timerList[0] finished executing submit_buygoods, _timerList[1] then go.
Is this a flaw of System.threading.timer when there is too many threads( actually just about 15 )?
What are the reasons? Any remedy? Will switching to Thread t = new Thread() helps?
Use Task instead of Thread, they are better for short jobs.
Task.Factory.StartNew(submit_buygoods);
P.S. Maybe you shouldn't hammer the server every 500ms, you could get your IP banned.

Fastest way to calculate time differences in C#?

It seems like there are a lot of ways to calculate time spans in c#. I am wondering which one is fastest and by that I simply means requires the least amount of processing. Let me throw out an example to illustrate exactly what I am trying to do.
private const int timeBetweenEvents = 250; //delay ms
DateTime nextUpdate = DateTime.Now.Add(new TimeSpan(0, 0, 0, timeBetweenEvents));
...
while(true)
{
if (DateTime.Now > nextUpdate)
{
// do something
nextUpdate = DateTime.Now.Add(new TimeSpan(0, 0, 0, timeBetweenEvents));
}
// ...
// do some other stuff
// ...
}
another option...
private const int timeBetweenEvents = 250; //delay ms
TimeSpan nextUpdate = DateTime.Now.TimeOfDay.Add(new TimeSpan(0,0,0,timeBetweenEvents));
...
while(true)
{
if (DateTime.Now.TimeOfDay > nextUpdate)
{
// do something
nextUpdate = DateTime.Now.TimeOfDay.Add(new TimeSpan(0, 0, 0, timeBetweenEvents));
}
// ...
// do some other stuff
// ...
}
I have also seen similar things by doing subtractions using System.Environment.TickCount. So what is the bst way to do this?
DateTime, Environment.TickCount and Thread.Sleep have a resolution of 30ms - which may cause problems. Stopwatch doesn't have this problem (on platforms that support it, i.e. pretty much any machine today) - plus the code is also a little shorter (the fastest code is code that is never executed) and clearer.
const long millisecondsBetweenEvents = 250;
var sw = new Stopwatch();
sw.Start();
while(true)
{
if (sw.ElapsedMilliseconds > millisecondsBetweenEvents)
{
// do something
sw.Restart();
}
}
If you're looking for performance, at the very least cache the value of DateTime.Now outside of the loop. I remember reading it can be a relatively expensive function to call.
I would use a Timer
A StopWatch will have better precision.

Implement c# timeout

Is it bad practice to use such while loop?
Maybe it is better to use Stopwatch, or maybe this solution has some pitfalls?
public void DoWork()
{
//do some preparation
DateTime startTime = DateTime.Now;
int rowsCount = 0;
int finalCount = getFinalCount();
do
{
Thread.Sleep(1000);
rowsCount = getRowsCount(); // gets rows count from database, rows are added by external app.
} while (rowsCount < finalCount && DateTime.Now - startTime < TimeSpan.FromMinutes(10));
}
I saw this article Implement C# Generic Timeout,
but it is too complex to use in simple scenarios - you need to think about sync of threads, is it proper to abort them or not and so on.
As I understand it, you want your method to do some work until it's done or until some period of time has elapsed? I would use a Stopwatch for that, and check the elapsed time in a loop:
void DoWork()
{
// we'll stop after 10 minutes
TimeSpan maxDuration = TimeSpan.FromMinutes(10);
Stopwatch sw = Stopwatch.StartNew();
DoneWithWork = false;
while (sw.Elapsed < maxDuration && !DoneWithWork)
{
// do some work
// if all the work is completed, set DoneWithWork to True
}
// Either we finished the work or we ran out of time.
}
It is better to use the System.Timers.Timer class.

Categories