2012-05-04 9 views
3

私はWPFを使用して非常に単純なストップウォッチに取り組んでいますが、System.Diagnosticsストップウォッチを使用して非常に遅く、私のアプリケーションから1秒ごとに私のシステムクロックと比較して全く信頼性がありませんでした。ストップウォッチの代わりに?

ストップウォッチについての検索が遅かったり、結果がたくさん見つかりましたが解決策が見つからなかったので、自分のカウンターを用意することにしました。ここで

は私が思い付いたのサンプルです:

System.Windows.Threading.DispatcherTimer _update; 
DateTime _started; 
bool isRunning = false; 

更新スレッド:

_update = new System.Windows.Threading.DispatcherTimer(new TimeSpan(0, 0, 0, 0, 1), System.Windows.Threading.DispatcherPriority.Normal, delegate 
{ 
    if (isRunning) 
     iTimer.Content = new DateTime((DateTime.Now - _started).Ticks).ToString("HH:mm:ss"); 
}, this.Dispatcher); 

私は2つのボタンがあり、bToggle、開始、停止、それを再開するためのresposibleであるとbResetという別のボタン。

private void bReset_Click(object sender, RoutedEventArgs e) 
{ 
    isRunning = false; 
    iTimer.Content = "00:00:00"; 
    bToggle.Content = "Start"; 
} 

private void bToggle_Click(object sender, RoutedEventArgs e) 
{ 
    if ((string)bToggle.Content == "Start") 
    { 
     isRunning = true; 
     _started = DateTime.Now; 
     bToggle.Content = "Stop"; 
    } 
    else if ((string)bToggle.Content == "Resume") 
    { 
     isRunning = true; 
     bToggle.Content = "Stop"; 
    } 
    else 
    { 
     isRunning = false; 
     bToggle.Content = "Resume"; 
    } 
} 

これは正常に動作しますが、停止して再開すると実際の時間が使用されているため、実際の時間まで秒が飛びます。

この問題を解決するにはどうすればよいですか、実際には現時点で精度の良いストップウォッチの代替手段がありますか?

+0

あなたは背景にしたDispatcherPriorityを設定し、低い周波数を使用する必要がありますか? – Oded

+0

ストップウォッチャーの場合は?それを簡単にするために、0から停止またはリセットまでカウントします。 – Guapo

+1

タイマーとして使ってみたようですね。 – Oded

答えて

2

誰かが停止をクリックするたびに経過時間を保存する追加の変数TimeSpan accumulatedTimeを導入する必要があります。

そして:

iTimer.Content = (new DateTime((DateTime.Now - _started).Ticks) + accumulatedTime).ToString("HH:mm:ss"); 
+0

すばらしい点、ありがとうございます。 – Guapo

+0

非常に感謝して、私はそれを次のように解決しました: '新しいDateTime((DateTime.Now.Subtract(accumulationTime) - _tempo).Ticks).ToString(" HH:mm:ss ");' – Guapo

1

使用System.Timers.Timer

あなたは開始と停止これを、イベントをチェックタイマーカウンタを設定することができます。

これは単純な例です:

_update = new System.Windows.Threading.DispatcherTimer(new TimeSpan(0, 0, 0, 0, 1), System.Windows.Threading.DispatcherPriority.Normal 

それはあなたがあなたの代理人がしたいことをWPFに指示します:私は、この行が問題だと思う

<Grid> 
    <StackPanel> 
     <Button Name="btnStartStop" Content="start/stop timer" Click="btnStartStop_Click" /> 
     <TextBlock Name="tbTime" Text="00:00" /> 
    </StackPanel> 
</Grid> 
+0

私が使用している事実スレッドは私のアプリケーションUIをハングしないようにしています – Guapo

+0

あなたのUIをロックすることはありませんが、あなたがバックグラウンドワーカーにタイマーを入れて、ワーカーのイベントに転送したい場合はprogresschangedイベント – jrb

+0

jrbそれはアプリケーションのウィンドウです。 – Guapo

0

public partial class MainWindow : Window 
{ 
    private Timer _timer; 
    private int _time; 

    public MainWindow() 
    { 
     InitializeComponent(); 

     _time = 0; 

     _timer = new Timer(1000); 
     _timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed); 
    } 

    void _timer_Elapsed(object sender, ElapsedEventArgs e) 
    { 

     Dispatcher.Invoke(new Action(() => 
             { 
              _time++; 
              tbTime.Text = _time.ToString(); 
             })); 

    } 

    private void btnStartStop_Click(object sender, RoutedEventArgs e) 
    { 
     if (_timer.Enabled) 
     { 
      _timer.Stop(); 
     } 
     else 
     { 
      _timer.Start(); 
     } 
    } 
} 

XAML毎秒1000回実行し、2番目に高い優先度でスケジュールを設定します。これはRenderDataBindよりも優先順位が高く、実際にはiTimer.Contentに入れた更新値を表示するにはRenderとDataBindの両方が必要だと思います。 ( - 人間はとにかく、50 fpsのより速いものを見ることができません。例えば20ミリ秒)あなたは `StopWatch`を使用していた何

+0

私の質問のコードでは、それはちょうど良い更新がストップウォッチクラスを使用していないので、私の意見では問題としてその行を切るだろう。 – Guapo