0

I am doing an application that needs a some kind of a system clock, a clock that counts ticks. I should be able to get the count value and set it.

I have done it using Thread library in the Python language, yet I could not do the same thing with the Timer class in C#. As someone new to .NET, I am not sure how this timer class works. I would love to to be able to implement the same clock using .NET.

Here is my Python code, so you can get an idea of what I'm talking about.

class SystemClock(threading.Thread):

  def __init__(self , timeUnit , sched):
      self.val = 0

      self.unit = timeUnit
      self.stp= False
      self.sched = sched
      threading.Thread.__init__(self)

  def run(self):
      while not self.stp:
          self.val +=1
          time.sleep(self.unit)

  def getSystemTime(self):
      return self.val

  def stop(self):
      self.stp = True

I appreciate your help;

1
  • 1
    Your Python code makes for a very poor timer, it quickly falls behind. At least use Environment.TickCount or DateTime.Now, it doesn't require a thread. Commented Dec 7, 2010 at 23:57

3 Answers 3

3

Why not just use System.Diagnostics.Stopwatch, as that's exactly what it's for.

// at the start of your program
Stopwatch SystemClock = Stopwatch.StartNew();

// any time you want to see how much time has elapsed
long ticks = SystemClock.ElapsedTicks;

If you really need to be able to set the value, then wrap this in a class that has a base_time value (in ticks), and then add the elapsed ticks to your base time to get the time you want.

Sign up to request clarification or add additional context in comments.

Comments

1

Is there any reason why you don't just retrieve a DateTime at the start and, as necessary to have the value, use an DateTime.Now.Subtract(origDateTime) and use the TimeSpan result for what you need? Or is this updating something with every tick?

EDIT Also, as with Timers, you set a "Tick" interval, so you don't need to sleep them. Every tick will execute the callback saving you the trouble of using a while...sleep. But bare in bind, while in threading territory, and I can't verify as it's been a while since I've used timers, you may need to lock() the variable you're modifying as it's in a separate thread as nothing is securing that another method isn't altering the same value.

EDITv3

Here's version 3 of the edit. You have two classes, both avoiding the use of a timer (which your CPU will thank me later ;-p) SystemClock is a typical one-per-second interval rate. VariableSystemClock allows you to specify the rate of the increases. I also changed the way you get the value from a property to a method, and even used inheritance. ;-)

SystemClock.cs

public class SystemClock
{
    protected DateTime _start;

    public SystemClock()
    {
        this._start = DateTime.UtcNow;
    }

    public virtual Int32 getSystemTime()
    {
        return Convert.ToInt32(Math.Floor(DateTime.UtcNow.Subtract(this._start).TotalSeconds));
    }
}

VariableSystemClock.cs

public class VariableSystemClock : SystemClock
{
    private TimeSpan _interval;

    public VariableSystemClock(TimeSpan interval)
        : base()
    {
        this._interval = interval;
    }

    public override Int32 getSystemTime()
    {
        Double ellapsed = DateTime.UtcNow.Subtract(this._start).Ticks / this._interval.Ticks;
        return Convert.ToInt32(Math.Floor(ellapsed));
    }
}

program.cs (so you can test it in a console application (project->new->console application)

class Program
{
    static void Main(string[] args)
    {
        SystemClock oncePerSecond = new SystemClock();
        VariableSystemClock oncePerInterval = new VariableSystemClock(TimeSpan.FromSeconds(2));

        Console.WriteLine("Start:");
        Console.WriteLine("  oncePerSecond:   {0}", oncePerSecond.getSystemTime());
        Console.WriteLine("  oncePerInterval: {0}", oncePerInterval.getSystemTime());
        Console.WriteLine();

        for (Int32 i = 0; i < 10; i++)
        {
            // sleep three seconds
            System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2));

            // display output
            Console.WriteLine("Interval {0}:", i);
            Console.WriteLine("  oncePerSecond:   {0}", oncePerSecond.getSystemTime());
            Console.WriteLine("  oncePerInterval: {0}", oncePerInterval.getSystemTime());
            Console.WriteLine();
        }

        Console.WriteLine("End:");
        Console.WriteLine("  oncePerSecond:   {0}", oncePerSecond.getSystemTime());
        Console.WriteLine("  oncePerInterval: {0}", oncePerInterval.getSystemTime());
        Console.WriteLine();
    }
}

Feel free to play with both the oncePerInterval construct and the Sleep within the for loop.

2 Comments

No Reason , if there is an alternative way i would be happy if you show me
And yet another update, hopefully that will give you some insight without the use of threading. ;-)
0

Thread Timers may be more what you're after.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.