6

I have create a little engineering app for some network debugging. It takes a list of IP addresses and pings them, with user set timeout and rate. It logs the average round-trip time and every time one of the sends fails it logs it's duration of failure and a timestamp of when it happened...

That's the idea. I developed it on a Win7 machine with .Net4 and have had to put the thing on a set of XP laptops.

The problem is the duration values on my box during testing show nice ms durations, on the XP boxes when I look they show 0 or 15.625 (magic number?)... and have the funny square, box symbol in the string?

    public void LinkUp()
    {
        if (_isLinkUp) return;

        _upTime = DateTime.Now;
        var span = _upTime.Subtract(_downTime);
        _downTimeLog.Add(new LinkDown()
                            {
                                _span = span,
                                _status = _ipStatus,
                                _time = _downTime
                            });
        _isLinkUp = true;
    }

That's the bit that does the log. The _ipStatus is the ping failure reason (typically timeout).

    _downEventLog.AppendLine("  Duration-> " + linkDownLogEvent._span.TotalMilliseconds + "ms\n");

That's the bit that does the print... Can anyone shed any light on this apparent difference?

The question has been answered but I will include an edit here for some more info.

EDIT:

It seems that the difference was down not to the Win7 and WinXP difference but 32bit and 64bit.

In a 32 bit windows systems as Henk points out, the granularity of the system clock is 15-16ms, this is what gave me the value of 15.625 for every value less than 16ms for the timespan.

In a 64 bit system the system call is to a different set of methods that have a much finer granularity. So on my dev machine in x64 I had ms accuracy from my system clock!

Now, the stopwatch uses a hardware interface via the processor instrumentation to record a much finer granularity (probably not every processor tick, but I imagine something obscenely accurate in-line with this thinking). If the hardware underlying the OS does not have this level of instrumentation, it will however use the system time. So beware! But I would guess most modern desktops/laptops have this instrumentation... Embedded devices or things of that nature might not, but then the stopwatch class is not in the Compact Framework as far as I can see (here you have to use QueryPerformanceCounter()).

Hope all this helps. It's helped me a lot.

Somewhere around the _spanStopWatch initialiser:

    if (!_spanStopWatch.IsHighResolution)
    {
        throw new ThisMachineIsNotAccurateEnoughForMyLikingException("Find a better machine.");
    }

The nuts and bolts:

    public void LinkUp()
    {
        if (_isLinkUp) return;

        _spanStopWatch.Stop();
        var span = _spanStopWatch.Elapsed;
        _downTimeLog.Add(new LinkDown()
                            {
                                _span = span,
                                _status = _ipStatus,
                                _time = _downTime
                            });
        _isLinkUp = true;
    }
Community
  • 1
  • 1
tigerswithguitars
  • 2,497
  • 1
  • 31
  • 53
  • Whilst it's probably not the solution to your problem, you should be using TotalMilliseconds.ToString() to explicitly convert to a string rather than do it implicitly. – Polynomial Oct 20 '11 at 08:47
  • 2
    @Polynomial this is absolutely unnecessary, since it will produce exact same code. – Petr Abdulin Oct 20 '11 at 08:51

1 Answers1

5

0 or 15.625 (magic number?)

Yes, using DateTime.Now is accurate only to the length of a CPU timeslice, 15-20 ms depending on your hardware and OS version.

Use System.Diagnostics.Stopwatch for more accurate timing.

H H
  • 263,252
  • 30
  • 330
  • 514
  • 2
    +1; Then if you experience problems with `Stopwatch`, check this question: http://stackoverflow.com/questions/3400254/can-the-net-stopwatch-class-be-this-terrible – Merlyn Morgan-Graham Oct 20 '11 at 09:03
  • I have read some more... I think it is this granularity thing. My dev machine is 64 bit... so uses a different call which has a finer granularity. – tigerswithguitars Oct 20 '11 at 09:27
  • @Henk Could you provide a snippet for the stopwatch usage? I'll peruse MSDN, but it's always nice to have an experienced users input! Many thanks guys. – tigerswithguitars Oct 20 '11 at 09:28
  • It was much easier than I thought to implement... Brilliant. Gives me even greater accuracy as well, my boss will be pleased :P – tigerswithguitars Oct 20 '11 at 09:34