C# 为计时器创建一个十进制值,显示下一个滴答声的持续时间

C# 为计时器创建一个十进制值,显示下一个滴答声的持续时间,c#,timer,decimal,C#,Timer,Decimal,我想创建一个从计时器中获取的0到1的值。该值将描述距离下一个勾号的时间。0是距离刻度最远的(以毫秒为单位)0.5是距离刻度的一半,1是刻度的时间 我怎样才能做到这一点呢?一个简单的选择是使用。在启动计时器时启动它,并在每个计时处理程序的开始处调用-实际上,您可以通过添加处理程序来单独执行此操作,只需在添加“真实”处理程序之前重新启动秒表即可 然后你会使用: double progress = stopwatch.Elapsed.TotalMilliseconds / timer.Interval

我想创建一个从计时器中获取的0到1的值。该值将描述距离下一个勾号的时间。0是距离刻度最远的(以毫秒为单位)0.5是距离刻度的一半,1是刻度的时间


我怎样才能做到这一点呢?

一个简单的选择是使用。在启动计时器时启动它,并在每个计时处理程序的开始处调用-实际上,您可以通过添加处理程序来单独执行此操作,只需在添加“真实”处理程序之前重新启动秒表即可

然后你会使用:

double progress = stopwatch.Elapsed.TotalMilliseconds / timer.Interval;
请记住,有时可能会超过1,因为计时器可能会延迟触发,具体取决于UI线程正在执行的其他操作。请注意,这提供了一个
double
而不是
decimal
,但我认为这更适合这种情况


如何封装它实际上取决于您试图做什么以及程序的其余部分如何连接在一起。。。我们目前没有足够的信息来指导您。类似的方法可以奏效,但考虑到计时器回调发生时所涉及的抖动量,您最多只能得到一个近似值:

class MyResourceIntensiveTimer : IDisposable
{
  private Stopwatch Stopwatch     ;
  private Timer     Timer         ;
  private long      PrevTick      ;
  private long      PeriodInTicks ;

  public Decimal TicksToNextTock
  {
    get
    {
      long elapsedTicks = Stopwatch.ElapsedTicks - PrevTick ;
      decimal value = ((decimal)elapsedTicks) / ((decimal)this.PeriodInTicks) ;
      return value ;
    }
  }

  public MyResourceIntensiveTimer( TimeSpan period )
  {
    if ( period <= TimeSpan.Zero ) throw new ArgumentOutOfRangeException("period") ;
    this.PeriodInTicks = period.Ticks ;
    this.Timer    = new Timer( TimerCallback , null , period , period ) ;
    this.PrevTick = (this.Stopwatch=Stopwatch.StartNew()).ElapsedTicks ;
    return ;
  }

  private void TimerCallback( object o )
  {
    this.PrevTick = Stopwatch.ElapsedTicks ;
    this.OnTock.Invoke() ;
    return ;
  }

  public event Action OnTock ;

  public void Dispose()
  {

    if ( this.Stopwatch != null )
    {
      if ( this.Stopwatch.IsRunning )
      {
        this.Stopwatch.Stop() ;
      }
      this.Stopwatch = null ;
    }

    if ( this.Timer != null )
    {
      this.Timer.Change(Timeout.Infinite , Timeout.Infinite ) ; // shut things down
      this.Timer = null ;
    }

  }

}
类MyResourceIntensiveTimer:IDisposable
{
私人秒表;
私人定时器;
私人长PrevTick;
私人长假;
公共十进制滴答声
{
得到
{
长elapsedTicks=秒表。elapsedTicks-前刻度;
十进制值=((十进制)elapsedTicks)/((十进制)this.PeriodInTicks);
返回值;
}
}
公共MyResourceIntensiveTimer(时间跨度周期)
{

如果(滴答声有多长?老实说,还不清楚你要的是什么……滴答声在1000到3000毫秒之间变化。我想知道,如果我离一个间隔为3000毫秒的计时器上的滴答声有1500毫秒的距离,我的十进制值将是0.5。那么你的计时器的结构是什么?它是基于
秒表
,还是系统时间?如果没有更多信息,很难为您提供帮助…对不起!我指的是visual studio express 2012中标准.net工具箱中的常规“计时器”。那么您指的是system.Windows.Forms.Timer吗?在.net中至少有三个不同的计时器类。。。