I am designing an industrial hardware control program in C#, which will run for periods of 72 hours at a time talking over serial ports.
In psuedo-code, what I am trying to do looks like this:-
while(true) {
TalkToSerialPort1();
WaitForXHours(3);
TalkToSerialPort2();
WaitForXHours(1);
// etc
}
I have this code in a separate thread from my main console or GUI program and has to be run procedureally
It seems like Thread.Sleep() for long periods of time seems to be ruining my day! I am looking for a reliable way of sleeping for extended periods of time.
Any information would be helpful.
You should use Quartz .NET it is reliable and very accurate scheduler.
Read more here: https://www.quartz-scheduler.net/
Alternative approach would be to use a Timer
for example calling method on every x minutes
Note : that in this case - You must ensure that previous operation has finished, before starting a new one.
A Stopwatch is a better way to solve this**. For example:
Stopwatch spw = new Stopwatch();
int stepNo = 0;
while (!haltWork)
{
Thread.Sleep(100);
switch (stepNo)
{
case 0:
TalkToSerialPort1();
spw.Restart();
stepNo += 1;
break;
case 1:
if (spw.Elapsed.Hours >= 3)
{
TalkToSerialPort2();
spw.Restart();
stepNo += 1;
}
break;
case 2:
if (spw.Elapsed.Hours >= 1)
{
TalkToSerialPort3();
spw.Restart();
stepNo += 1;
}
break;
// etc...
}
}
Here I've added a condition haltWork - your main program will need some way to signal this thread to exit in a timely fashion if necessary. This runs the thread in a polling loop that will allow it to break and exit, supports user cancellation, and, because of the stopwatch, will provide you the precise time elapsed for the current step in the case of user cancellation that you can use for process diagnostics, restart procedures, etc.
The procedural process is broken up into steps using a switch statement. This lets you perform long running procedural processes with waiting or polling steps in a clean and logical manner while also remaining responsive, able to provide active feedback (consider raising events periodically to alert the main thread of your current step, time elapsed, etc, for process logging purposes).
Note also that this example resets the stopwatch at each step - how you do this depends on your requirements; whether you need to control the interval between steps or whether it is more important to keep regular pace with respect to an arbitrary reference. If the latter, naturally just start the stopwatch once and make the rest of your intervals absolute rather than relative.
** I am proceeding from the assumption that doing this inside your C# application has been thought out carefully and that this is the best place to take responsibility for this task.
The windows task scheduler is one alternative place to handle repetitive "headless" tasks that need to be run at long intervals.
Another alternative, especially relevant to industrial control, is to use dedicated hardware to do this - a small PLC, etc.
well - if You want to stick to the "while (true)" pattern,
what You can do is smth like this:
while (true){
if (DateTime.Now - LastExecutionDate > 72h)
{
doYourStuff();
Update_LastExecutionDate;
}
else{
continue; //or sleep for 5 minutes
}
Related
When going through a really long array, or have a complicated calculations per each index, is there a way to yield after iterating through the array for the maximum amount of time. The maximum amount of time is the maximum time per each frame.
For example:
for(int i = 0; i < 100000; i++){
do something complicated;
if(maximum amount of time /*right before the user feels lag*/)
yield; (come back and resume i where it last yielded)
}
}
//order does not matter
So basically, what I want to achieve is high percent usage for the cpu, however, I do not want it to go beyond 100%, which the user will experience lag
edit:
Sorry for the little confusion. A more clear example might be 3d rendering in a program such as blender. When the user hits render, it calculates each pixels to determine what color it needs to be. When one looks at the cpu usage, it is close to 100%. however, it does not freeze while it calculates the pixels while it calculates the maximum amount as possible
If you are running your code on multiple CPUs (as implied by the multithreading tag), there should (in the usual case) be no need to stop executing the loop in order for your user interface to remain responsive. Perform the calculation on one or more background threads, and have those background threads update the UI thread as appropriate.
is there a way to yield after iterating through the array for the maximum amount of time
If by yield you mean just stop (and restart from the beginning next frame), then sure. You can pass a CancellationToken to your thread, and have it periodically check for a cancellation request. You can use a timer at the start of each frame to fire off that request, or more likely, use an existing mechanism that already does end-of-frame processing to trigger the thread to stop work.
If by yield you mean stop where I am and resume at that place at the start of the next frame, I would ask why stop given that you have multiple CPUs. If you must stop, you can use the CancellationToken as before, but just keep track of where you are in the loop, resuming from there instead of at the start.
So basically, what I want to achieve is high percent usage for the cpu, however, I do not want it to go beyond 100%, which the user will experience lag
You can never go over 100% CPU usage by definition. To avoid the feeling of lag when the CPU utilization is high, use thread priorities to ensure that the foreground thread has a higher priority than your background threads.
Unless I'm missing something....
double MAX_PROCESSTIME = 50.0;
DateTime loopStart = DateTime.Now();
for(int i = 0; i < 100000; i++){
// do something complicated;
double timePassed = (DateTime.Now() - loopStart).TotalMilliseconds;
if(timePassed > MAX_PROCESSTIME)
{
break;
}
}
How about you consider use a push model instead, to iterate in parallel and raising an event so the consumer just treat each item as they come?
Usually the solution to this problem is to move the work to a separate thread that can't interrupt the UI, and let the UI or a controller thread cancel the work when called for.
Another option is that I've read somewhere typical humans have a perception level of about 25 milliseconds; two events are perceived to occur at the same time as long as they are less than 25 milliseconds apart. Sadly, I can no longer find the original reference, but I did at least find a corroborating article. You can use this fact to set a timer for about that long and let the process run as much as you want until the timer goes off. You may also want to account for the atypical human as well, especially if your app is in an area catering to people that may have above average reflexes.
I write a c# program to count down 5 seconds. What I do is:
new Task(() =>
{
try
{
this.Invoke((Action)delegate()
{
label1.Text = "5"; // 4, 3, 2..etc
});
}
Thread.Sleep(1000);
}
catch
{
// form could be disposed
break;
}
}
}).Start();
This works on my PC, however, when I copied the program to a window tablet, the Thread.Sleep(1000) gives more than 1 second. In other words, it takes more than 5 seconds (in fact more than 10 seconds) to update the label from 5,4,3,2,1. Alternatively, it takes too long to update label1.Text = "5", etc? It does not make sense to me. I wonder what is wrong?
Sleep will wait at least that long before activating the thread again, but it can always be longer than that. After the one second time has passed the thread becomes eligible to execute by the CPU scheduler, and the scheduler is able to run it whenever it wants to. If it's particularly busy, and/or is using a scheduling algorithm that doesn't focus on quickly allowing newly active threads to run, it could be some time.
Servy's answer is correct. For more details, please read the documentation:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686298.aspx
which states:
Note that a ready thread is not guaranteed to run immediately. Consequently, the thread may not run until some time after the sleep interval elapses. For more information, see Scheduling Priorities.
The priority documentation is here:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms685100.aspx
More generally though: you are doing something deeply wrong. Do not ever use Sleep like this. If you want to wait some amount of time then use a timer or use a Delay task. Never sleep a thread like this outside of test code. The right way to write your code is probably something like
for (int countdown = 5; countdown > 0; countdown -= 1)
{
label1.Text = countdown.ToString();
await Task.Delay(1000);
}
Or, make a class that has a timer and a counter, start the timer to tick a few times a second, compare the current time to the time when you last updated the label, and if more than a second has elapsed, update the label.
I have a multi-threaded application, and in a certain section of code I use a Stopwatch to measure the time of an operation:
MatchCollection matches = regex.Matches(text); //lazy evaluation
Int32 matchCount;
//inside this bracket program should not context switch
{
//start timer
MyStopwatch matchDuration = MyStopwatch.StartNew();
//actually evaluate regex
matchCount = matches.Count;
//adds the time regex took to a list
durations.AddDuration(matchDuration.Stop());
}
Now, the problem is if the program switches control to another thread somewhere else while the stopwatch is started, then the timed duration will be wrong. The other thread could have done any amount of work before the context switches back to this section.
Note that I am not asking about locking, these are all local variables so there is no need for that. I just want the timed section to execute continuously.
edit: another solution could be to subtract the context-switched time to get the actual time done doing work in the timed section. Don't know if that's possible.
You can't do that. Otherwise it would be very easy for any application to get complete control over the CPU timeslices assigned to it.
You can, however, give your process a high priority to reduce the probability of a context-switch.
Here is another thought:
Assuming that you don't measure the execution time of a regular expression just once but multiple times, you should not see the average execution time as an absolute value but as a relative value compared to the average execution times of other regular expressions.
With this thinking you can compare the average execution times of different regular expressions without knowing the times lost to context switches. The time lost to context switches would be about the same in every average, assuming the environment is relatively stable with regards to CPU utilization.
I don't think you can do that.
A "best effort", for me, would be to put your method in a separate thread, and use
Thread.CurrentThread.Priority = ThreadPriority.Highest;
to avoid as much as possible context switching.
If I may ask, why do you need such a precise measurement, and why can't you extract the function, and benchmark it in its own program if that's the point ?
Edit : Depending on the use case it may be useful to use
Process.GetCurrentProcess().ProcessorAffinity = new IntPtr(2); // Or whatever core you want to stick to
to avoid switch between cores.
I am currently trying to write an application that runs the same code exactly 100 times a second. I have done some testing using the built-in timers of the .NET framework. I've tested the System.Threading.Timer class, the System.Windows.Forms.Timer class and the System.Timers.Timer class. None of them seem to be accurate enough for what I am trying to do.
I've found out about PerformanceCounters and am currently trying to implement such in my application.
However, I am having a bit of trouble with my program taking up a whole core of my CPU when idling.
I only need it to be active 100 times a second. My loop looks like this:
long nextTick, nextMeasure;
QueryPerformanceCounter(out start);
nextTick = start + countsPerTick;
nextMeasure = start + performanceFrequency;
long currentCount;
while (true)
{
QueryPerformanceCounter(out currentCount);
if (currentCount >= nextMeasure)
{
Debug.Print("Ticks this second: " + tickCount);
tickCount = 0;
nextMeasure += performanceFrequency;
}
if (currentCount >= nextTick)
{
Calculations();
tickCount++;
nextTick += countsPerTick;
}
}
As you can see, most of the time the program will be waiting to run Calculations() again by running through the while loop constantly. Is there a way to stop this from happening? I don't want to slow the computers my program will be run on down.
System.Thread.Thread.Sleep unfortunately is also pretty "inaccurate", but I would be okay with using it if there is no other solution.
What I am basically asking is this: Is there a way to make an infinite loop less CPU-intensive? Is there any other way of accurately waiting for a specific amount of time?
As I'm sure you're aware, Windows is not a real-time O/S, so there can never be any guarantee that your code will run as often as you want.
Having said that, the most efficient in terms of yielding to other threads is probably to use Thread.Sleep() as the timer. If you want higher accuracy than the default you can issue a timeBeginPeriod with the desired resolution down to a millisecond. The function must be DLLImported from winmm.dll.
timeBeginPeriod(1) together with a normal timer or Thread.Sleep should work decently.
Note that this has a global effect. There are claims that it increases power consumption, since it forces the windows timer to run more often, shortening the CPU sleeping periods. This means you should generally avoid it. But if you need highly accurate timing, it's certainly a better choice than a busy-wait.
I'm working on a console application which will be scheduled and run at set intervals, say every 30 minutes. Its only purpose is to query a Web Service to update a batch of database rows.
The Web Service API reccommends calling once every 30 seconds, and timeout after a set interval. The following pseudocode is given as an example:
listId := updateList(<list of terms>)
LOOP
WHILE NOT isUpdatingComplete(listId)
END LOOP
statuses := getStatuses(“LIST_ID = {listId}”)
I have coded this roughly in C# as:
int callCount = 0;
while( callCount < 5 && !client.isUpdateComplete(listId, out messages) )
{
listId = client.updateList(options, terms, out messages);
callCount++;
Thread.Sleep(30000);
}
// Get resulting status...
Is it OK in this situation to use Thread.Sleep()? I'm aware it is not generally good practice but from reading reasons not to use it this seems like acceptable usage.
Thanks.
Thread.Sleep ensures the current thread doesn't return until at least the specified milliseconds have passed. There are plenty of places it's appropriate to do that, and your example seems fine, assuming it's running on a background thread.
Some example places you don't want to use it - on the UI thread or where you need to do exact timing.
Generally speaking, Thread.Sleep is like any other tool: perfectly OK to use, except when it's terribly misused. I disagree with the "not generally good practice" part, which is the result of people abusing Thread.Sleep when they should be doing something else (i.e. blocking on a synchronization object).
In your case the program is single-threaded, it has no UI (i.e. the thread has no message loop) and you do not want to synchronize with external events. Therefore Thread.Sleep is just fine.
The general objection against Sleep() is that it wastes a Thread.
In your case there is only 1 Thread (maybe 2) so that is not really a problem.
So I think it looks fine (but I would sleep 29 seconds to cut some slack).
It's fine, except that you cannot interrupt it once it goes into sleep, without aborting the thread (which is not recommended).
That's why a ManualResetEvent might be a better idea, since it can be signalled ("awaken") from a different thread.
you could stick with the Thread.Sleep method. But it would be more elegant to schedule it to run every 30 minutes - so you don't have to take care of the waiting inside your application.
Thread.Sleep isn't the best for executing periodic logic. Thread.Sleep(n) means your thread will relinquish control for n milliseconds. There is no guarantee that it will regain control after n milliseconds, it depends on the CPU load.
If you are locking the thread for 30 mins case you should schedule a windows task every 30 mins, so the program executes and then ends. That way you are not locking a thread for so long.
For shorter times, like 30 secs / 1 min, System.Thread.Sleep() is perfectly fine. For more than 5 mins i would use a windows task. (Im spanish i think on the english version are called like that, im talking about the tasks you schedule from the control panel ;-) )