I need to format the day time using QueryPerformanceCounter Win32 API.
The format, is: HH:mm:ss.ffffff , containing hours minuts seconds and microseconds.
I need to use THIS function, because another process (written in C) is using this function and the purpose is using the same function in both places.
Thanks
The System.Diagnostics.Stopwatch class uses QueryPerformanceCounter(), saves you from having to P/Invoke it.
You should not use QueryPerformanceCounter to determine time of day. It can only be used to determine an elapsed interval with a very high resolution as it returns the number of ticks that passed since the computer was last restarted.
As such, at best, you may only determine how many hours, minutes, and seconds have passed since a previous reading of QueryPerformanceCounter which must not have happened too long in the past.
In order to convert from ticks to seconds you need to determine the frequency (using QueryPerformanceFrequency) of the ticks on the computer you're running the QueryPerformanceCounter function and then divide your reading by that frequency:
// obtain frequency
long freq;
QueryPerformanceFrequency(freq);
// then obtain your first reading
long start_count;
long end_count;
QueryPerformanceCounter(start_count)
// .. do some work
// obatin your second reading
QueryPerformanceCounter(end_count);
// calculate time elapsed
long milliseconds_elapsed = (long)(((double)(end_count - start_count) / freq) * 1000);
// from here on you can format milliseconds_elapsed any way you need to
An alternative to the above example would be to use the TimeSpan structure available in .Net which has a constructor that takes ticks like so:
// then obtain your first reading
long start_count;
long end_count;
QueryPerformanceCounter(start_count)
// .. do some work
// obatin your second reading
QueryPerformanceCounter(end_count);
TimeSpan time_elapsed = new TimeSpan(end_count - start_count);
Console.WriteLine("Time Elapsed: " + time_elapsed.ToString());
Can use :
1) The System.Diagnostics.Stopwatch class uses QueryPerformanceCounter(), saves you from having to P/Invoke it.
2) Can use directly by importing from the Win32 dll . [DLLImport(Win32)] and the name ofthe function
Possibly I misunderstand the question, as for me none of the previous answers are relevant at all.
I had the problem (which sent me here): Given a value from QueryPerformanceCounter, because something out of my control specifies timestamps using that function, how can I convert these values to a normal date / time?
I figured that QueryPerformanceCounter returns the number of seconds since the system booted, multiplied (and extended in resolution) depending on QueryPerformanceFrequency.
Thus, the most simple solution is to get the current date/time, subtract the amount of seconds returned by QueryPerformanceCounter/QueryPerformanceFrequency, and then add the values you like to format as time of day.
Related
I am passing data from a c++ .dll through to a C# application using DllImport.
What i would like to do is time the data transfer time. So I would like to get the system time in milliseconds in the dll function, and then do the same again on the C# side, and get the difference between the two to calculate the time taken.
On the c++ side, I am sending a long that I am getting like this:
boost::posix_time::ptime current_date_microseconds = boost::posix_time::microsec_clock::local_time();
long millisecondStamp2 = current_date_microseconds.time_of_day().total_milliseconds();
I send that long through to C# as a variable named timestamp, and then run:
long milliseconds = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
long elapsed = milliseconds - timestamp;
When I print the values they look like this:
63705280140098 //c#
54540098 //c++
63705225600000 // elapsed
Why are the c++ value and the C# value so different?
How can I get equivalent values from the system clock in this way?
Please ignore the comment that claims that .NET DateTime ticks are divided into two parts. That comment is not correct. The DateTime.Ticks property returns a tick count that has units of "one ten-millionth of a second", and which measures the number of such ticks from "0:00:00 UTC on January 1, 0001, in the Gregorian calendar". It is a straight integer value, with all of the bits contributing equally according to their significance in the value to the total.
Now, as far as the discrepancy in your result goes…
The C++ expression current_date_microseconds.time_of_day().total_milliseconds() is giving you the total milliseconds for the day. I.e. that's the total number of milliseconds since midnight (based on the value, appears you executed the code around 3PM local time).
On the other hand, the .NET expression using DateTime.Now is measuring milliseconds since the start of the epoch, i.e. since Jan 1, 0001.
The two values are not comparable at all. They represent two completely different time periods.
In theory, you could fix this problem by using instead, for the .NET side, DateTime.Now.TimeOfDay.TotalMilliseconds. This would get you a lot closer to the value you expected.
However…
It's not clear to me that there's any guarantee that the C++ POSIX API you're using will use exactly the same clock reference as the .NET API. Furthermore, even if it is, there is some overhead in the API itself, along with thread-scheduling perturbations that may introduce error into the calculation.
It seems to me that a much better approach would be for you on the .NET side to use the System.Diagnostics.Stopwatch class to measure the entire time that the call into the C++ DLL takes, and then in the C++ DLL, use your POSIX API to measure the time that the C++ code takes to execute and pass that back to the C# side.
Then the C# side can just subtract the C++ time from its own time, to determine roughly what the total overhead of the call was. (Making sure, of course, to use exactly the same units for each value…e.g. milliseconds.)
Even so, it's important to keep in mind:
If you return the C++ time value in the same call, that in and of itself could affect the total overhead of the call.
Some of the apparent overhead could be thread-scheduling effects. I.e. if your thread gets pre-empted during the call, then part of your measurement will be the time during which the thread was pre-empted.
At least on the .NET side, and probably on the C++ side as well, there are still limitations to the precision of the timing. The Stopwatch class is definitely more precise and preferable over DateTime, but if the overhead is small enough, you may not get useful results (but of course, if it's that small, then it's probably good enough to discover that it's too small to get useful results :) ).
I am extremely confused with this stopWatch.Elapsed property. It shows the time value in this format
I want to know what should I add in the end of this output. Is it ms (01:20:17.0550410ms) or just s (01:20:17.0550410s)?
And further more if I want to take only the msportion of this output and do some calculation with it which value should I take, is it .0550410 or 55.041? My questions might sound silly but I'm really confused!
please help.
The unit shown is "fractional parts of a second", to the 7th decimal place - i.e. to the 10-millionth of a second.
Since a millisecond is 0.001 seconds, your number of milliseconds is 55.041.
Now, as everyone else said, use stopWatch.Elapsed.TotalMilliseconds (to get all of the milliseconds) or stopWatch.Elapsed.Milliseconds (to get all of the milliseconds less than 1 second).
I am extremely confused with this stopWatch.Elapsed property. It shows the time value in this format
I'll begin at the beginning, just to make sure everything is understood.
Microsoft .Net framework designers have decided that all variables that store information derive from either a Class or a Struct(ture). Both of these base types have some defaults methods. One of these Methods for a ValueType (which I'll discuss below) is .ToString(). When you call the ToString() method on a Windows Runtime structure, it provides the default behavior for value types that don’t override ToString().
I will assuming you are talking about the System.Diagnostics.Stopwatch class. The documentation states:
A Stopwatch instance can measure elapsed time for one interval, or the total of elapsed time across multiple intervals. In a typical Stopwatch scenario, you call the Start method, then eventually call the Stop method, and then you check elapsed time using the Elapsed property.
Before we begin looking at the Properties of the Stopwatch, we need to understand that in order for the Stopwatch to work, there needs to be a way to store a Magnitude of Time (information). A Magnitude of Time in this case a numerical representation of the difference between two points in time; in this case the when the Stopwatch Starts and when the Stopwatch Ends. Microsoft .Net has created a structure called TimeSpan to store this value.
Taking a look at the documentation for the property Stopwatch.Elapsed it is of the type TimeSpan.
Since your screenshot appears to be in a console application, I'll assume the code (which should always be provided but isn't) is the following:
Console.Writeline("Took Time: " + stopWatch.Elapsed.ToString());
This code converts the TimeSpan into a string using the TimeSpan's .ToString() override:
So not passing a value to .ToString() is a null value which defaults to ("c") It's in the TimeSpan Format Strings:
So using your example:
01:20:17.0550410s
It should be obvious that 01 is hours, 20 is minutes, 17 is seconds and .0550410 are tenths of seconds (decisecond). Adding any string values at the end will most likely make no sense because all the numbers are of different time durations. The only way I think it would make sense if you wanted be more specific is to change it to:
01h 20m 17.0550410s
or
01h 20m 17s 055.0410ms
According to the documentation for TimeSpan:
A TimeSpan value can be represented as [-]d.hh:mm:ss.ff, where [...] ss is seconds, and ff is fractions of a second
So in your case, it is 17.0550410 seconds.
Elasped is a TimeSpan, what you're showing is the representation from writing it to the console (Same as calling .ToString() on any non string object), that representation is in hours:minutes:seconds.fraction of second. If you want to show this in a specific amount there are properties for this on the TimeSpan so instead of doing
Console.WriteLine(stopWatch.Elapsed);
You can do
Console.WriteLine(stopWatch.Elapsed.TotalMilliseconds);
A full example to clarify
Console.WriteLine(
"The timer ran for " + stopWatch.Elapsed.Hours + " Hours, "
+ stopWatch.Elapsed.Minutes + " Minutes and "
+ stopWatch.Elapsed.Seconds + ". this amounts to a total of "
+ stopWatch.Elapsed.TotalMilliseconds + " ms" );
It looks like you are just using the default .ToString() method of the Stopwatch.Elapsed property, which actually is a TimeSpan object. You can absolutely control the string formatting of this TimeSpan, as well as use numeric components of it for mathematical operations (rounding, adding, etc.). Please read this: Stopwatch.Elapsed Property
A quick search of 'c# stopwatch' returns the MSDN documentation showing that Stopwatch.Elapsed is a TimeSpan. Then a search on 'c# TimeSpan' returns the MSDN documentation showing that TimeSpan.ToString() returns a string with the following format: [-][d.]hh:mm:ss[.fffffff]. And that's just using google. Next time try doing some research before asking your question.
Assuming that you are interested in StopWatch.Elapsed, then...
In situations like this I find the documentation is often quite helpful.
It states that StopWatch.Elapsed returns
A read-only TimeSpan representing the total elapsed time measured by the current instance.
The documentation for TimeSpan states its many available properties, one of which is Milliseconds and another is TotalMilliseconds. According to the docs:
Milliseconds - Gets the milliseconds component of the time interval represented by the current TimeSpan structure.
whereas
TotalMilliseconds - Gets the value of the current TimeSpan structure expressed in whole and fractional milliseconds.
Other properties allow you to check Days, Hours, Minutes, Seconds etc. Please use the documentation as it saves everyone a lot of time and effort.
I am trying to calculate a video framerate in a program. To do this I take
DateTime.Now
at the beginning of a stream, and then again after every frame whilst also incrementing a framecounter.
Then I calculate the FPS like so:
int fps = (int)(frames / (TimeSpan.FromTicks(CurrentTime.Ticks).Seconds - TimeSpan.FromTicks(StartTime.Ticks).Seconds));
The problem is that I occassionally get a negative number out, meaning the start time must be later than the current time. How can this be the case? Does anyone know anough about these functions to explain?
Seconds gives you the seconds part of the TimeSpan, not the total duration of the TimeSpan converted in seconds. This means that Seconds will never be greater than 60.
Use TotalSeconds instead
You should consider using StopWatch for such needs, It has much better precision
The datetime functions are probably not precise enough for your needs, you may want to look into performance counters instead. I think the StopWatch class is what your looking for. System.Diagnostics.StopWatch. that is using the QueryPerformanceFrequency and QueryPerformanceCounter functions for the timing.
We are currently rewritting the core of our services, basically we have scheduled tasks that can run on intervals, dates, specific times etc etc etc.
Currently we're wondering if daylightsaving might cause trouble for us, basically we calculate the next possible runtime, based on what days the task should execute and between what times, and what interval. We do this by taking the current time, and adding days/minutes/hours to this DateTime.
We then take this new run time and subtract DateTime.Now from this DateTime, leaving us with the timespan untill the next run.
How ever, what if the current time is 01:50 on a daylightsavings day, we add 20 minutes, which is our set interval, and end up with a time of 02:10, how ever since this is daylightsavinds, it's actually 01:10.
When i subtract the current time (01:50) from the 01:10 (which is actually 02:10) does this return a negative value which i need to work around or does this never ever return a negative value because DateTime is just a long underneath holding the proper information?
Basically, the following code, is the check needed or not?
//Get interval between nextrun and right now!
double interval = (NextRun - DateTime.Now).TotalMilliseconds;
//Check if interval is ever less or equal to 0, should never happen but maybe with daylight saving time?
if(interval <= 0)
{
//Set default value
interval = IntervalInMilliseconds;
}
We believe that this check isn't needed but our googling so far hasn't given us a definative answer.
Use DateTime.UtcNow instead of DateTime.Now EVERYWHERE
First of all, you can try it yourself as it will help you understand how it works.
Essentially, using your example above, if you have 20 minutes to a local time, it would be 2:10 and not 1:10 as the computation is done in local time. If you want to get 1:10, you need to convert local time to universal time, add 20 minutes and then convert back to local time.
If you want real elapsed time, then you have to convert time to universal time before computing time difference. Also, if you work in local time, you won't be able to differentiate ambiguous time when the clock goes back.
Up until now I used DateTime.Now for getting timestamps, but I noticed that if you print DateTime.Now in a loop you will see that it increments in descrete jumps of approx. 15 ms. But for certain scenarios in my application I need to get the most accurate timestamp possible, preferably with tick (=100 ns) precision. Any ideas?
Update:
Apparently, StopWatch / QueryPerformanceCounter is the way to go, but it can only be used to measure time, so I was thinking about calling DateTime.Now when the application starts up and then just have StopWatch run and then just add the elapsed time from StopWatch to the initial value returned from DateTime.Now. At least that should give me accurate relative timestamps, right? What do you think about that (hack)?
NOTE:
StopWatch.ElapsedTicks is different from StopWatch.Elapsed.Ticks! I used the former assuming 1 tick = 100 ns, but in this case 1 tick = 1 / StopWatch.Frequency. So to get ticks equivalent to DateTime use StopWatch.Elapsed.Ticks. I just learned this the hard way.
NOTE 2:
Using the StopWatch approach, I noticed it gets out of sync with the real time. After about 10 hours, it was ahead by 5 seconds. So I guess one would have to resync it every X or so where X could be 1 hour, 30 min, 15 min, etc. I am not sure what the optimal timespan for resyncing would be since every resync will change the offset which can be up to 20 ms.
The value of the system clock that DateTime.Now reads is only updated every 15 ms or so (or 10 ms on some systems), which is why the times are quantized around those intervals. There is an additional quantization effect that results from the fact that your code is running in a multithreaded OS, and thus there are stretches where your application is not "alive" and is thus not measuring the real current time.
Since you're looking for an ultra-accurate time stamp value (as opposed to just timing an arbitrary duration), the Stopwatch class by itself will not do what you need. I think you would have to do this yourself with a sort of DateTime/Stopwatch hybrid. When your application starts, you would store the current DateTime.UtcNow value (i.e. the crude-resolution time when your application starts) and then also start a Stopwatch object, like this:
DateTime _starttime = DateTime.UtcNow;
Stopwatch _stopwatch = Stopwatch.StartNew();
Then, whenever you need a high-resolution DateTime value, you would get it like this:
DateTime highresDT = _starttime.AddTicks(_stopwatch.Elapsed.Ticks);
You also may want to periodically reset _starttime and _stopwatch, to keep the resulting time from getting too far out of sync with the system time (although I'm not sure this would actually happen, and it would take a long time to happen anyway).
Update: since it appears that Stopwatch does get out of sync with the system time (by as much as half a second per hour), I think it makes sense to reset the hybrid DateTime class based on the amount of time that passes between calls to check the time:
public class HiResDateTime
{
private static DateTime _startTime;
private static Stopwatch _stopWatch = null;
private static TimeSpan _maxIdle =
TimeSpan.FromSeconds(10);
public static DateTime UtcNow
{
get
{
if ((_stopWatch == null) ||
(_startTime.Add(_maxIdle) < DateTime.UtcNow))
{
Reset();
}
return _startTime.AddTicks(_stopWatch.Elapsed.Ticks);
}
}
private static void Reset()
{
_startTime = DateTime.UtcNow;
_stopWatch = Stopwatch.StartNew();
}
}
If you reset the hybrid timer at some regular interval (say every hour or something), you run the risk of setting the time back before the last read time, kind of like a miniature Daylight Savings Time problem.
To get a high-resolution tick-count, please, use the static Stopwatch.GetTimestamp()-method:
long tickCount = System.Diagnostics.Stopwatch.GetTimestamp();
DateTime highResDateTime = new DateTime(tickCount);
just take a look at the .NET Source Code:
public static long GetTimestamp() {
if(IsHighResolution) {
long timestamp = 0;
SafeNativeMethods.QueryPerformanceCounter(out timestamp);
return timestamp;
}
else {
return DateTime.UtcNow.Ticks;
}
}
Source Code here: http://referencesource.microsoft.com/#System/services/monitoring/system/diagnosticts/Stopwatch.cs,69c6c3137e12dab4
[The accepted answer does not appear to be thread safe, and by its own admission can go backwards in time causing duplicate timestamps, hence this alternative answer]
If what you really care about (per your comment) is in fact, a unique timestamp that is allocated in strict ascending order and which corresponds as closely as possible to the system time, you could try this alternative approach:
public class HiResDateTime
{
private static long lastTimeStamp = DateTime.UtcNow.Ticks;
public static long UtcNowTicks
{
get
{
long orig, newval;
do
{
orig = lastTimeStamp;
long now = DateTime.UtcNow.Ticks;
newval = Math.Max(now, orig + 1);
} while (Interlocked.CompareExchange
(ref lastTimeStamp, newval, orig) != orig);
return newval;
}
}
}
These suggestions all look too hard! If you're on Windows 8 or Server 2012 or higher, use GetSystemTimePreciseAsFileTime as follows:
[DllImport("Kernel32.dll", CallingConvention = CallingConvention.Winapi)]
static extern void GetSystemTimePreciseAsFileTime(out long filetime);
public DateTimeOffset GetNow()
{
long fileTime;
GetSystemTimePreciseAsFileTime(out fileTime);
return DateTimeOffset.FromFileTime(fileTime);
}
This has much, much better accuracy than DateTime.Now without any effort.
See MSDN for more info: http://msdn.microsoft.com/en-us/library/windows/desktop/hh706895(v=vs.85).aspx
It does return the most accurate date and time known to the operating system.
The operating system also provides higher resolution timing through QueryPerformanceCounter and QueryPerformanceFrequency (.NET Stopwatch class). These let you time an interval but do not give you date and time of day. You might argue that these would be able to give you a very accurate time and day, but I am not sure how badly they skew over a long interval.
1). If you need high resolution absolute accuracy: you can't use DateTime.Now
when it is based on a clock with a 15 ms interval (unless it
is possible "slide" the phase).
Instead, an external source of better resolution absolute
accuracy time (e.g. ntp), t1 below, could be combined with the high
resolution timer (StopWatch / QueryPerformanceCounter).
2). If you just need high resolution:
Sample DateTime.Now (t1) once together with a value from the
high resolution timer (StopWatch / QueryPerformanceCounter)
(tt0).
If the current value of the high resolution timer is tt then the
current time, t, is:
t = t1 + (tt - tt0)
3). An alternative could be to disentangle absolute time and
order of the financial events: one value for absolute time
(15 ms resolution, possibly off by several minutes) and one
value for the order (for example, incrementing a value by one each
time and store that). The start value for the order can be
based on some system global value or be derived from the
absolute time when the application starts.
This solution would be more robust as it is not dependent on
the underlying hardware implementation of the clocks/timers
(that may vary betweens systems).
This is too much work for something so simple. Just insert a DateTime in your database with the trade. Then to obtain trade order use your identity column which should be an incrementing value.
If you are inserting into multiple databases and trying to reconcile after the fact then you will be mis-calculating trade order due to any slight variance in your database times (even ns increments as you said)
To solve the multiple database issue you could expose a single service that each trade hits to get an order. The service could return a DateTime.UtcNow.Ticks and an incrementing trade number.
Even using one of the solutions above anyone conducting trades from a location on the network with more latency could possibly place trades first (real world), but they get entered in the wrong order due to latency. Because of this the trade must be considered placed at the database, not at users' consoles.
The 15 ms (actually it can be 15-25 ms) accuracy is based on the Windows 55 Hz/65 Hz timer resolution. This is also the basic TimeSlice period. Affected are Windows.Forms.Timer, Threading.Thread.Sleep, Threading.Timer, etc.
To get accurate intervals you should use the Stopwatch class. It will use high-resolution if available. Try the following statements to find out:
Console.WriteLine("H = {0}", System.Diagnostics.Stopwatch.IsHighResolution);
Console.WriteLine("F = {0}", System.Diagnostics.Stopwatch.Frequency);
Console.WriteLine("R = {0}", 1.0 /System.Diagnostics.Stopwatch.Frequency);
I get R=6E-08 sec, or 60 ns. It should suffice for your purpose.
I'd add the following regarding MusiGenesis Answer for the re-sync timing.
Meaning: What time should I use to re-sync ( the _maxIdle in MusiGenesis answer's)
You know that with this solution you are not perfectly accurate, thats why you re-sync.
But also what you implicitly want is the same thing as Ian Mercer solution's:
a unique timestamp that is allocated in strict ascending order
Therefore the amount of time between two re-sync ( _maxIdle Lets call it SyncTime) should be function of 4 things:
the DateTime.UtcNow resolution
the ratio of accuracy you want
the precision level you want
An estimation of the out-of-sync ratio of your machine
Obviously the first constraint on this variable would be :
out-of-sync ratio <= accuracy ratio
For example : I dont want my accuracy to be worst than 0.5s/hrs or 1ms/day etc... (in bad English: I dont want to be more wrong than 0.5s/hrs=12s/day).
So you cannot achieve a better accuracy than what the Stopwatch offer you on your PC. It depends on your out-of-sync ratio, which might not be constant.
Another constraint is the minimum time between two resync:
Synctime >= DateTime.UtcNow resolution
Here accuracy and precision are linked because if you using a high precision (for example to store in a DB) but a lower accuracy, You might break Ian Mercer statement that is the strict ascending order.
Note: It seems DateTime.UtcNow may have a bigger default Res than 15ms (1ms on my machine) Follow the link:
High accuracy DateTime.UtcNow
Let's take an example:
Imagine the out-of-sync ratio commented above.
After about 10 hours, it was ahead by 5 seconds.
Say I want a microsec precision. My timer res is 1ms (see above Note)
So point by point:
the DateTime.UtcNow resolution : 1ms
accuracy ratio >= out-of-sync ratio,
lets take the most accurate possible so : accuracy ratio = out-of-sync ratio
the precision level you want : 1 microsec
An estimation of the out-of-sync ratio of your machine : 0.5s/hour (this is also my accuracy)
If you reset every 10s, imagine your at 9.999s, 1ms before reset.
Here you make a call during this interval. The time your function will plot is ahead by : 0.5/3600*9.999s eq 1.39ms.
You would display a time of 10.000390sec. After UtcNow tick, if you make a call within the 390micro sec, your will have a number inferior to the previous one. Its worse if this out-of-sync ratio is random depending on CPU Load or other things.
Now let's say I put SyncTime at its minimum value > I resync every 1ms
Doing the same thinking would put me Ahead of time by 0.139 microsec < inferior to the precision I want. Therefore if I call the function at 9.999 ms, so 1microsec before reset I will plot 9.999. And just after I will plot 10.000. I will have a good order.
So here the other constraint is : accuracy-ratio x SyncTime < precision level , lets say to be sure because number can be rounded up that accuracy-ratio x SyncTime < precision level/2 is good.
The issue is resolved.
So a Quick recap would be :
Retrieve your timer resolution.
Compute an estimate of the out-of-sync ratio.
accuracy ratio >= out-of-sync ratio estimate , Best accuracy = out-of-sync ratio
Choose your Precision Level considering the following:
timer-resolution <= SyncTime <= PrecisionLevel/(2*accuracy-ratio)
The best Precision you can achieve is timer-resolution*2*out-of-sync ratio
For the above ratio (0.5/hr) the correct SyncTime would be 3.6ms, so rounded down to 3ms.
With the above ratio and the timer resolution of 1ms. If you want a one-tick Precision level (0.1microsec), you need an out-of-sync ratio of no more than : 180ms/hour.
In its last answer to its own answer MusiGenesis state:
#Hermann: I've been running a similar test for the last two hours (without the reset correction), and the Stopwatch-based timer is only running about 400 ms ahead after 2 hours, so the skew itself appears to be variable (but still pretty severe). I'm pretty surprised that the skew is this bad; I guess this is why Stopwatch is in System.Diagnostics. – MusiGenesis
So the Stopwatch accuracy is close to 200ms/hour, almost our 180ms/hour. Is there any link to why our number and this number are so close ? Dont know. But this accuracy is enough for us to achieve Tick-Precision
The Best PrecisionLevel: For the example above it is 0.27 microsec.
However what happen if I call it multiple times between 9.999ms and the re-sync.
2 calls to the function could end-up with the same TimeStamp being returned the time would be 9.999 for both (as I dont see more precision). To circumvent this, you cannot touch the precision level because it is Linked to SyncTime by the above relation. So you should implement Ian Mercer solution's for those case.
Please don't hesitate to comment my answer.
If need the timestamp to perform benchmarks use StopWatch which has much better precision than DateTime.Now.
I think this is the best way to solve this issue:
long timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();