Does C# Stopwatch pause when my computer goes to sleep? [closed] - c#

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I'm measuring the runtime of my program (written in C#) with Stopwatch. My computer went sleep, and I don't know that the time data it shows is correct or not. So is Stopwatch measuring the sleep time too or it was paused then continued?

According to source code for StopWatch the method Start looks like this:
public void Start() {
// Calling start on a running Stopwatch is a no-op.
if(!isRunning) {
startTimeStamp = GetTimestamp();
isRunning = true;
}
}
The method Stop looks like this:
public void Stop() {
// Calling stop on a stopped Stopwatch is a no-op.
if( isRunning) {
long endTimeStamp = GetTimestamp();
long elapsedThisPeriod = endTimeStamp - startTimeStamp;
elapsed += elapsedThisPeriod;
isRunning = false;
if (elapsed < 0) {
// When measuring small time periods the StopWatch.Elapsed*
// properties can return negative values. This is due to
// bugs in the basic input/output system (BIOS) or the hardware
// abstraction layer (HAL) on machines with variable-speed CPUs
// (e.g. Intel SpeedStep).
elapsed = 0;
}
}
}
So the answer of your question is: It measures the duration by using two timestamps which leads to the conclusion that it doesn't matter whether your computer goes to sleep or not.
Update (thanks Mike and Joe):
However, if your computer is sleeping, it cannot run your program - so the measured duration would be the sum of the duration the program has been running and the duration where the computer has been sleeping.
TotalDuration = CalculationDuration + SleepDuration.

The stopwatch does not pause when the computer enters sleep.
It uses the Windows API QueryPerformanceCounter() function, which does not reset the count when the computer goes to sleep:
"QueryPerformanceCounter reads the performance counter and returns the
total number of ticks that have occurred since the Windows operating
system was started, including the time when the machine was in a sleep
state such as standby, hibernate, or connected standby."

Related

Is there a way to limit the CPU usage of OTHER applications?

So, my brother was playing Fortnite and it was lagging quite a bit. So I offered to make an application that will limit the CPU usage of other apps, but I actually am having trouble with getting the limit to go on the other application.
Here's the code I've tried:
public void ThrottledLoop(Action action, int cpuPercentageLimit)
{
Stopwatch stopwatch = new Stopwatch();
while (true)
{
stopwatch.Reset();
stopwatch.Start();
long actionStart = stopwatch.ElapsedTicks;
action.Invoke();
long actionEnd = stopwatch.ElapsedTicks;
long actionDuration = actionEnd - actionStart;
long relativeWaitTime = (int)(
(1 / (double)cpuPercentageLimit) * actionDuration);
Thread.Sleep((int)((relativeWaitTime / (double)Stopwatch.Frequency) * 1000));
}
}
Please help, if there is any other information you need just let me know.
Thanks
Summary from comments above.
You can specify what processors ("affinity") processes are allowed to run on. This offers more fine grain control than setting process priority.
e.g. limit certain processes to say the last 4 cores on a system with 16 logical cores but allowing Fortnite to use whatever it wants. Be aware, some apps might not take too kindly to it.
Anti-virus programs sometimes play nice by keeping themselves at the end of the list of cores in a system.
For an example take a look at the Windows Task Manager Details tab.
See also
How can I set processor affinity to a thread or a Task in .NET?

Why is my application becoming less responsive over time?

I'm debugging a C# application that becomes almost unresponsive after a few days. The application calculates memory/CPU usage every second and displays it in the footer of the main UI.
The cause for the unresponsiveness is because of the time it takes to fetch the RawValue of a PerformanceCounter ("Working Set - Private"). After a couple of days, it takes almost a second to fetch the RawValue, freezing the main UI thread. If I restart my computer, everything is fast again for a few days until it slowly becomes less responsive. If I recompile this application without the PerformanceCounter code (it's open source), it runs normally immediately.
To rule out that it's the application, here's some sample code that does the exact same thing:
static void Main(string[] args)
{
using (var memoryWorkingSetCounter = new PerformanceCounter("Process", "Working Set - Private", Process.GetCurrentProcess().ProcessName, true))
{
while (!Console.KeyAvailable)
{
var memoryWorkingSetSw = new Stopwatch();
memoryWorkingSetSw.Start();
var memoryWorkingSetValue = memoryWorkingSetCounter.RawValue;
memoryWorkingSetSw.Stop();
Console.WriteLine(memoryWorkingSetValue.ToString());
Console.WriteLine(memoryWorkingSetSw.Elapsed.ToString());
Thread.Sleep(TimeSpan.FromSeconds(1));
}
}
Console.Read();
}
I left this running for ~2.5 days and graphed the Elapsed time in milliseconds:
What could cause a performance counter in Windows to become slow over time? Could another app be not cleaning it up? Is there a way to debug which apps are also looking at this performance counter? I'm on Windows 10.
why you declare Stopwatch inside a loop?
remove any new declaration possible inside loops.
when you do so the memory is increasing overtime and you count on garbage collector to do the work

Chip-8 Emulator: slow down clock speed

I'm planning to write a nes emulator. But first, to understand how emulation works, I'll write a Chip-8 emulator.
The emulator is nearly finished. I've some bugs in games, but this will be fixed soon.
My problem number 1 is to synchronize the emulator with the clock speed of the Chip-8.
In the internet I've often read, that the general clock speed should be ~ 540Hz. The timers of the chip should be ticked at a frequenz of 60Hz.
To synchronize my emulator with the Chip-8 I've written follow logic:
private void GameTick()
{
Stopwatch watch = new Stopwatch();
var instructionCount = 0;
_gameIsRunning = true;
while (_gameIsRunning)
{
watch.Restart();
EmulateCycle();
//Updates the internal timer at a 60hz frequenz
//540hz (game tick) divided by 9 equals 60hz (timer tick)
instructionCount++;
if(instructionCount == 9)
{
UpdateSoundAndDelay();
instructionCount = 0;
}
if (_readyToDraw)
{
DrawGraphics();
_readyToDraw = false;
}
SetKeys();
//Pause the game to get a virtual clock speed of ca. 540mhz
var elapsedMicroseconds = watch.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L));
while(elapsedMicroseconds < 1852)
{
elapsedMicroseconds = watch.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L));
}
}
}
For more detailed information look at my repo: https://github.com/Marcel-Hoffmann/Chip-8-Emulator
As you can see, for each cpu cycle, I'll wait for 1852 microseconds. The result will be ~ 540 cycles in a second equals to 540Hz.
But I'm not very happy with this logic.
Has someone a better Idea, how to synchronize the clock speed?
This is the typical approach, and has many drawbacks - most notably, unnecessary CPU usage and potentially scheduling issues (your application will be seen as 100% CPU beast, so other applications might get their thread quanta before you under load).
A better approach would use a sleep instead - however, by default, the system timer has nowhere near the frequency to accommodate a wait that's less than 2ms. So if you want to use a sleep, you'll need to change the system timer. This is a bit tricky on older Windows (it's a system-wide setting and has noticeable impact on other applications and general CPU usage), but even in that case, it's better than a "busy loop" - as long as you restore the system settings afterwards. On Windows 8 (and to some extent, 7 and Vista), the timer is asynchronous and no longer requires a busy loop, so it's a lot easier to have higher timer resolution.
The system timer APIs are not exposed by .NET, so you'll need to use P/Invokes (timeBeginPeriod and timeEndPeriod for the old-style API). If this isn't available, you can always fall back to your busy loop :)

How do I fire an event every 20ms *on average*? Inbuilt timer "creeps"

I'm writing an RTP server to publish PCMA wave files. It needs to pump data every 20ms (on average - it can be a bit either side of that for any 1 pump, but must average out at 20ms).
My current implementation uses a Timer, but then the event fires just over every 20 ms, so it gradually drifts out.
Is there a better way to do this? The only way I can currently think of is to dynamically adjust the timer inteval as it starts to creep, in order to bring it back in line.
Sample Code
void Main()
{
System.Timers.Timer timer = new System.Timers.Timer();
// Use a stopwatch to measure the "wall-clock" elapsed time.
Stopwatch sw = new Stopwatch();
sw.Start();
timer.Elapsed += (sender, args) =>
{
Console.WriteLine(sw.ElapsedMilliseconds);
// Simulate doing some work here -
// in real life this would be pumping data via UDP.
Thread.Sleep(300);
};
timer.AutoReset = true;
// I'm using an interval of 1 second here as it better
// illustrates the problem
timer.Interval = 1000;
timer.Start();
}
Output:
1002
2001
3002
4003
5003
6005
7006
8007
9007
10017
11018
12019
13019
14020 <-- By this point we have creeped over 20 ms in just 14 iterations :(
First of all: I will never get it to be exact because your program will never be in full control of what the CPU's are doing as long as you are running on standard Windows because it is not a real-time OS. Just think of a anti virus kicking in, the Garbage Collector freezing your thread, playing a game on the side, ...
That said you might be able to compensate a bit.
When the handler kicks in, pause the timer, record the current time, act, update the time's interval by setting the interval to the required interval based upon the start of the handler and the time it has taken to act.
This way you can control the creeping better. An exception to that might be when the acting takes longer than the interval and whether the interval should contain the time to act or be the time between to acts.
In my experience you cannot rely on any timer to get an interval that small (20 ms) accurately but compensating for creep can help quite a bit.
You could use StopWatch to measure time, but it doesn't have callbacks.
You can use Windows multimedia timer. It involves some WinAPI, but all the details are provided in this article.

System.Threading.Timer causing other Timers to fall behind

My first post here, but this site has answered many questions that I have had in the past. Hopefully I can give enough detail to explain the issue I am facing as I don't fully understand how all .NET is handling the threads I create!
OK so basically, I have a thread set to run every 1000ms which gets a frame counter from a video encoder and calculate the FPS. Accuracy is sufficient with a System.Threading.Timer for now though I realise it isn't accurate (often over 1000ms between events). I also have another Threading.Timer which is running and taking a reading from a network to serial device. The issue is that if the network device becomes unavailable and the socket timesout on that timer the FPS timers go completely out of sync! So they were previously executing every 1015ms (measured) but when I start this other Thread.Timer trying to make a socket connection and it fails it causes the FPS counter timers to go totally off (up to 7000ms!!). Am not quite sure why this should be and really need the FPS counter to run once a second pretty much no matter what.
Bit of code ->
FPS Counter
private void getFPS(Object stateInfo)//Run once per second
{
int frames = AxisMediaControl.getFrames; //Axis Encoder media control
int fps = frames - prevValue;
prevValue = frames;
setFPSBar(fps, fps_color); //Delegate to update progress bar for FPS
}
Battery Level Timer
while (isRunning)
{
if (!comm.Connected) //comm is standard socket client
comm.Connect(this.ip_address, this.port); //Timeout here causes other timer threads to go out of sync
if (comm.Connected)
{
decimal reading = comm.getBatt_Level();
//Calculate Readings and update GUI
Console.Out.WriteLine("Reading = " + (int)prog);
break;//Debug
}
This is the code used to connect to the socket currently ->
public Socket mSocket { get; set; }
public bool Connect(IPAddress ip_address, UInt16 port)
{
try
{
mSocket.Connect(ip_address, port);
}
catch(Exception ex)
{
}
return mSocket.Connected;
}
Hopefully not too ambiguous!
While I don't know why your FPS timer is not called for 7s, I can suggest a workaround: Measure the TimeSpan since the last time the FPS value was updated by remembering the Environment.TickCount value. Then, calculate the FPS value as (delta_frames / delta_t).
Thanks for the comments, I fixed it by doing the following.
Used a System.Timers.Timer instead and set auto-reset to false. Each time one of the timers completes I start it again, this means there is only ever one timer for each battery device. The problem with the initial solution is that the network timeout was causing the threads to stay alive for much longer than the timer interval. Thus, to ensure the timer interval was met a new thread was spawned more frequently.
During runtime this meant there was about 5-7 threads for each battery timer (whereby 6 are timing out and 1 is about to begin). Changing to the new timer means there is only one thread now as it should be.
I also added in the code to calculate the FPS based on the time taken (using Stopwatch function for higher accuracy (thanks USR)). Thanks for the help. I will have to make sure not to just leave exceptions blank too.

Categories