简体   繁体   中英

Using a timer thread in C#

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;

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.

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.

线程计时器可能更多。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM