- 1. Causes
-
2. Comparison of alternative solutions
- 2.1.
- 2.2.
- 2.3 Examples of use
- 3. Very precise solutions
- 4. Summary
1. Causes
In the daily development of is a commonly used asynchronous delay method. However, the
The timing is not always very accurate. For example:
-
system load
The timing accuracy may be affected by the system load. If the system load is high and CPU and other resources are heavily utilized, task scheduling may be delayed, resulting in the
The actual delay was longer than expected.
-
task scheduling
is based on the task scheduler, and the scheduling accuracy of the task scheduler may be affected by the operating system. The operating system's task scheduler schedules tasks based on the overall load and priority of the system, which may cause the
of the actual delay time is not precise enough.
-
Timer Accuracy
A system timer is used, and the precision of the system timer may be limited by the hardware and operating system. Different operating systems and hardware platforms may have different timer accuracies, which can affect the
The accuracy of the
-
power management In some cases, power management policies, such as energy-saving modes, may affect task scheduling and timer accuracy. For example, in power-saving mode, the CPU may reduce its frequency or go into hibernation, which affects the
The accuracy of the
-
GC (Garbage Collection)NET, garbage collection (GC) may suspend all managed threads, which affects the
The accuracy of the If there is an error in the
Garbage collection occurs during this period and the actual delay may be longer than expected.
The following is a sample code showing how to use the respond in singing
Stopwatch
to measure the actual delay time to better understand the The accuracy of the
using System;
using ;
using ;
public class Program
{
public static async Task Main(string[] args)
{
int delayMilliseconds = 1000; // 1unit of angle or arc equivalent one sixtieth of a degree
Stopwatch stopwatch = ();
await (delayMilliseconds);
();
($"Expected delay: {delayMilliseconds} ms");
($"Actual delay: {} ms");
}
}
In this example, we use theStopwatch
to measure of the actual delay time. You can run this sample code and observe the difference between the actual delay time and the expected delay time.
2. Comparison of alternative solutions
In addition we can use the maybe
. Below is a sample comparison of the two methods:
2.1.
Provides more accurate timing control, which can be avoided
Some of the inaccuracies of the
using System;
using ;
using ;
public class TimerExample
{
public async Task ExecuteWithTimer(int delayMilliseconds)
{
var tcs = new TaskCompletionSource<bool>();
using (var timer = new Timer(_ => (true), null, delayMilliseconds, ))
{
await ;
}
}
}
2.2.
Stopwatch
can be used to accurately measure time intervals in combination with the Realize more accurate timing control.
using System;
using ;
using ;
public class StopwatchExample
{
public async Task ExecuteWithStopwatch(int delayMilliseconds)
{
Stopwatch stopwatch = ();
while ( < delayMilliseconds)
{
await (1); // Short delay to avoid busy waiting
}
}
}
2.3 Examples of use
public class Program
{
public static async Task Main(string[] args)
{
int delayMilliseconds = 1000; // 1unit of angle or arc equivalent one sixtieth of a degree
// utilization
Stopwatch stopwatch1 = ();
await (delayMilliseconds);
();
($" - Expected delay: {delayMilliseconds} ms, Actual delay: {} ms");
// utilization
var timerExample = new TimerExample();
Stopwatch stopwatch2 = ();
await (delayMilliseconds);
();
($"Timer - Expected delay: {delayMilliseconds} ms, Actual delay: {} ms");
// utilization
var stopwatchExample = new StopwatchExample();
Stopwatch stopwatch3 = ();
await (delayMilliseconds);
();
($"Stopwatch - Expected delay: {delayMilliseconds} ms, Actual delay: {} ms");
}
}
3. Very precise solutions
Windows providesQueryPerformanceCounter
respond in singingQueryPerformanceFrequency
Two APIs to implement high precision timers. These two APIs provide microsecond timing accuracy.
- QueryPerformanceCounter: Get the current high precision timer value
- QueryPerformanceFrequency: Obtaining the frequency of a high-precision timer
[DllImport("")]
private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
[DllImport("")]
private static extern bool QueryPerformanceFrequency(out long lpFrequency);
// High-precision sleep function
static void HighPrecisionSleep(int milliseconds)
{
long start = 0, stop = 0, frequency = 0;
QueryPerformanceFrequency(out frequency);
QueryPerformanceCounter(out start);
long targetTicks = (frequency / 1000) * milliseconds;
do
{
QueryPerformanceCounter(out stop);
} while ((stop - start) < targetTicks);
}
4. Summary
even though、
、
It is accurate enough in most cases, but it can indeed be affected by factors such as system load, task scheduling, timer accuracy, power management and garbage collection, resulting in less accurate timing. By using the Windows API, we can achieve more accurate timing control.