2

Windows Phone 7 でカウントダウン タイマーを作成しようとしていますが、これはアプリケーションにとって非常に重要です。しかし、UI規則のテキストを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);

アプリのコンソール出力を実行すると、次のようになります。

#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

その不要な呼び出し (#3、#5、#7 など) を取り除く方法がわかりません。

アドバイスありがとうございます。

4

3 に答える 3

0

代わりにDispatcherTimerを使用する必要があります。次の例は、10 からカウントダウンを行うタイマーを示しています。

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();
    }
}
于 2012-07-16T22:33:19.517 に答える
0

次のモッドを試してください。

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();
    }
}

ちなみに、Shawn のコードは私のデバイスで問題なく動作しますが、問題が発生した場合は、a を使用してStopwatch、時間変数から経過時間を差し引いてください。また、DispatcherTimer200 ミリ秒のように (もちろんこの手法では) 少し速く実行して、精度を高めます (すべてが上記で実装されています)。それが役立つことを願っています。

于 2012-07-17T07:34:22.230 に答える
0

コードとコメントを見ると、アプリケーションの障害はタイマー コードではなく、タイマーを初期化するものにあると思われます。タイマーが 2 回作成されていると思われます。

投稿したブロックの外側のコードを見ずにこれをデバッグするのは難しいですが、説明した症状は、複数のタイマーと複数のスタック/クロージャー変数を初期化していることを示唆していますoldTimenewTime

簡単なレベルでは、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);
}
}
于 2012-07-17T07:47:50.013 に答える