简体   繁体   English

WP7上的计时器分派更改顺序混乱

[英]Timer dispatching changes out of order on WP7

I'm trying to make a countdown timer on Windows Phone 7, which is really important for my application. 我正在尝试在Windows Phone 7上设置一个倒数计时器,这对于我的应用程序确实很重要。 But I can't find any method to update text in UI regullary every one second. 但是我找不到任何一种方法来每秒更新一次UI regullary中的文本。

Timer dt = new System.Threading.Timer(delegate
{
 Dispatcher.BeginInvoke(() =>
   {
      newtime = oldtime--;
      System.Diagnostics.Debug.WriteLine("#" + counter.ToString() + 
                                         " new: " + newtime.ToString() + 
                                         " old: " + oldtime.ToString());
      counter++;
      oldtime = newtime;
   }
}, null, 0, 1000);

After running my app console output seems like this: 运行我的应用程序控制台后,输出看起来像这样:

 #1 new: 445 old: 446 #2 new: 444 old: 445 #3 new: 445 old: 446 #4 new: 443 old: 444 #5 new: 444 old: 445 #6 new: 442 old: 443 #7 new: 443 old: 444 #8 new: 441 old: 442 

I can't figure out how to get rid of that unwanted invokes (#3, #5, #7, etc.) 我不知道如何摆脱不必要的调用(#3,#5,#7等)

Thank you for any advice. 感谢您的任何建议。

You should use the DispatcherTimer instead. 您应该改用DispatcherTimer The following example shows a timer doing a countdown from ten. 下面的示例显示一个计时器从十开始倒数。

DispatcherTimer _timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
int _timeLeft = 10;

public MyClass()
{
    InitializeComponent();
    _timer.Tick += TimerTick;
    _timer.Start();
    MyTextBox.Text = _timeLeft.ToString();
}

void TimerTick(object sender, EventArgs e)
{
    _timeLeft--;
    if (_timeLeft == 0)
    {
        _timer.Stop();
        MyTextBox.Text = null;
    }
    else
    {
        MyTextBox.Text = _timeLeft.ToString();
    }
}

Try the following mod: 试试下面的mod:

DispatcherTimer _timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(200) };
int _timeLeft = 50;
Stopwatch watch = new Stopwatch();
public MainPage()
{
InitializeComponent();
_timer.Tick += TimerTick;
_timer.Start();
textBlock1.Text = _timeLeft.ToString();
watch.Start();
}
void TimerTick(object sender, EventArgs e)
{

    if ((_timeLeft - (int)watch.Elapsed.TotalSeconds) <= 0)
    {
        watch.Stop();
        _timer.Stop();
        textBlock1.Text = null;
    }
    else
    {
        textBlock1.Text = (_timeLeft - (int)watch.Elapsed.TotalSeconds).ToString();
    }
}

By the way Shawn's code just works fine on my device but if you're experiencing problems, just use a Stopwatch and subtract the elapsed time from your time variable. 顺便说一下,肖恩(Shawn)的代码在我的设备上可以正常工作,但是如果遇到问题,只需使用Stopwatch然后从时间变量中减去经过的时间即可。 Also, run DispatcherTimer a little faster (of course for this technique) like 200ms for greater accuracy (everything has been implemented above). 同样,以200毫秒的速度运行DispatcherTimer (这当然是针对该技术的)要快一点,以提高准确性(上面已实现了所有方法)。 Hope that helps. 希望能有所帮助。

Looking at the code and at the comments, I suspect that the fault with your application is not with the Timer code, but instead with whatever initialises the Timer - I suspect the timer is being constructed twice. 查看代码和注释,我怀疑您的应用程序的故障不是与Timer代码有关,而是与初始化Timer无关的东西-我怀疑计时器正在构造两次。

It's hard to debug this without seeing the code outside of the block you've posted, but the symptoms you describe suggest that you are initialising multiple Timers and multiple stack/closure variables oldTime and newTime 在看不到已发布的代码块之外的代码的情况下很难对其进行调试,但是您所描述的症状表明您正在初始化多个Timers和多个堆栈/关闭变量oldTimenewTime

At a simple level, you could try protecting the Timer construction - eg with something like: 简单来说,您可以尝试保护Timer的构造-例如,使用以下内容:

public class MyClass
{

// existing code...

private bool _timerStarted;

private void StartTimer()
{

if (_timerStarted)
{
    Debug.WriteLine("Timer already started - ignoring");
    return;
}

_timerStarted = true;

var newTime = 500;
var oldTime = 500;
var counter = 1;

Timer dt = new System.Threading.Timer(delegate
{
 Dispatcher.BeginInvoke(() =>
   {
      newtime = oldtime--;
      System.Diagnostics.Debug.WriteLine("#" + counter.ToString() + 
                                         " new: " + newtime.ToString() + 
                                         " old: " + oldtime.ToString());
      counter++;
      oldtime = newtime;
   }
}, null, 0, 1000);
}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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