1

在我的 wp7.5 应用程序中,我有一个需要显示秒表的块(比如 30、29、28...1、0)。我尝试了各种实现来使用 DispatchTimer 和 Timer 类来实现这一点,但它们都没有解决我的问题。

方法 1:这是我用于 DispatchTimer 的片段,

DispatcherTimer dt = new DispatcherTimer();
dt.Interval = new TimeSpan(0, 0, 1); // 1 second
dt.Tick += new EventHandler(dt_Tick);

for(int count=0;count<30;count++)
    dt.Start();

void dt_Tick(object sender, EventArgs e)
{
   // my UI control update here
}

在我的 Tick 事件实现中,我正在使用时间计数器更新 UI 控件。我在这里阅读了一些关于同一主题的问题,由于 UI 线程,调度程序滴答在某些情况下永远不会触发。它发生在我身上,tick 事件从未触发。

方法 2:我尝试使用 System.Threading.Timer 类,

Timer timer = new Timer(TimerProc);

for(int count=0;count<30;count++)
    timer.Change(1000, 0);

void TimerProc(object sender)
{
   // my UI control update here
}

我的方法都没有奏效。我可能会问一个重复的问题,谁能指出我在代码中做错了什么?

4

2 回答 2

2

调用 keep 的方法之后会在间隔经过时触发,直到DispatcherTimer您调用它为止。因此,您不需要调用30 次,但您必须维护一个计数器并在处理程序中在 30 个滴答声后停止计时器:Start()Tick eventStop()Start()Tick event

private int counter;

private void Start_Click(object sender, RoutedEventArgs e)
{
    counter = 30;
    DispatcherTimer dt = new DispatcherTimer();
    dt.Interval = new TimeSpan(0, 0, 1); // 1 second
    dt.Tick += new EventHandler(dt_Tick);
    dt.Start();
}

void dt_Tick(object sender, EventArgs e)
{
    if (counter >= 0)
    {
        timeText.Text = counter.ToString();
        counter--;
    }
    else
        ((DispatcherTimer)sender).Stop();
}

编辑:
如果 DispatcherTimer 的精度不够,您可以改用System.Threading.Timer,但在这种情况下,您可以调用Dispatcher.BeginInvoketick 事件处理程序以启用对 UI 线程上对象的访问:

private int counter;

private void Start_Click(object sender, RoutedEventArgs e)
{
    counter = 30;
    timeText.Text = counter.ToString();
    Timer dt = new Timer(dt_Tick);
    dt.Change(1000 /* delay to start the timer */, 1000 /* period time */);
}

private void dt_Tick(object sender)
{
    if (counter > 0)
    {
        Dispatcher.BeginInvoke(() => timeText.Text = counter.ToString());
        counter--;
    }
    else
        ((Timer) sender).Dispose();
}
于 2011-12-31T12:11:41.930 回答
0

Timer tick 方法不能是跟踪时间的方法。为什么?有两个原因。

1/ DispatcherTimer 的每个 Tick 之间的间隔并不精确,取决于您对 UI 的操作。它可以是 1 秒,就像它可以多一点。

2/ 下一个 Tick 在前一个 Tick 结束后一秒触发。由于tick内的更新代码需要一些时间,它会自动滞后。例如,如果更新代码耗时 0.1 秒,则在 1 秒后触发滴答声,更新完成,下一个滴答声在更新结束后 1 秒出现,因此在计时器开始后 2.1 秒!

因此,您应该存储启动 Timer 的时间,并计算每个滴答的经过时间:

    protected DispatcherTimer Timer { get; set; }

    protected DateTime TimerStartTime { get; set; }

    private void ButtonStart_Click(object sender, RoutedEventArgs e)
    {
        this.Timer = new DispatcherTimer();
        this.Timer.Interval = TimeSpan.FromSeconds(1);
        this.Timer.Tick += this.Timer_Tick;
        this.TimerStartTime = DateTime.Now;
        this.Timer.Start();
    }

    private void Timer_Tick(object sender, EventArgs e)
    {
        int elapsedSeconds = (int)DateTime.Now.Subtract(this.TimerStartTime).TotalSeconds;

        this.TextTimer.Text = (30 - elapsedSeconds).ToString();
    }

这样,即使每次滴答之间的时间不准确,计时器也不会指示错误时间。您甚至可以将计时器间隔减少到 500 毫秒或更短,以获得更精确的计时器,而无需更改 Tick 方法。

于 2011-12-31T13:28:20.727 回答