2011-11-01 4 views
10

私はC#を使用してカウントダウンを行い、形式で時刻を表示しようとしている:C#のカウントダウンタイマー

hour:minutes:seconds 

私はこれを試してみた:また、この問題を解決するための

var minutes = 3; //countdown time 
    var start = DateTime.Now; 
    var end = DateTime.Now.AddMinutes(minutes); 
    Thread.Sleep(1800); 
    if (??) // I tried DateTime.Now > end not works 
    { 
     //... show time 
     label1.Text = "..."; 
    } 
    else 
    { 
    //done 
     label1.Text = "Done!"; 
    } 

さまざまな方法を登場しました。

+0

定期的にラベルを更新する場合は、ループのようなものが必要です。 – svick

+2

@javasocute私は彼がした、私は彼の正気について私の疑問を持っていただろう。これはWinformsであり、.netはそのようなものに対処するための完璧な仕組みを持っています。このような小さな事のためにjavascriptを持ち込む必要はありません。 – CodesInChaos

答えて

28

ここではThread.Sleepを使用しないでください。 UIスレッドのThread.SleepはUIをブロックし、別のスレッドでこのスレッドを使用すると、スレッドの同期化によりさらに複雑になります。

C#5または非同期CTPを使用している場合は、UIをブロックしないThread.Sleepという継続コードに相当するコードを取得している可能性があるため、おそらくコードによく似たコードを書くことができます。

標準C#4では、System.Windows.Forms.Timerを使用します。あなたが書いたタイマハンドラでは

var minutes = 3; //countdown time 
var start = DateTime.UtcNow; // Use UtcNow instead of Now 
endTime = start.AddMinutes(minutes); //endTime is a member, not a local variable 
timer1.Enabled = true; 

は、カウントダウンを開始するには、他のフォーマットオプションについては

TimeSpan remainingTime=endTime-DateTime.UtcNow; 
if(remainingTime<TimeSpan.Zero) 
{ 
    label1.Text = "Done!"; 
    timer1.Enabled=false; 
} 
else 
{ 
    label1.Text = remainingTime.ToString(); 
} 

Standard TimeSpan Format Stringsを参照してください。

このコードに残っている1つの問題は、システムクロックが変更されても正しく動作しないことです。

DateTime.UtcNowの代わりにDateTime.Nowを使用すると、夏時間から/夏時間への切り替え時やタイムゾーンの変更時にも壊れます。表示時間ではなく特定の時点を特定したいので、現地時間の代わりにUTCを使用する必要があります。

+0

ありがとう! +1良い答えが、私はステートメントで1つの問題があります: 'エラー:演算子 '<'は 'System.TimeSpan'型と 'int'型のオペランドに適用できません。 –

+0

@ TheMask「0」ではなく「TimeSpan.Zero」を使用してください。 – CodesInChaos

+1

CodeInChaos:物事が実際に働く人。完璧に動作します。どうもありがとう。 :) –

0

あなたのコードは変数を設定し、3分間スリープ状態になるので、ifステートメントはスリープ状態から離れるまで実行されません。どちらかそれが動作しながら、あなたはまだあなたのプログラムの中でものを行うことができます第二のスレッドで

while (DateTime.now < end) { 
    label1.Text = "..."; 
    Thread.Sleep(#); //Pick a second, or 5 or whatever 
} 

label1.Text = "Done!"; 

... UIを更新するか、またはこのような何かをするために、新しいスレッドを設定します。 「完了!」それが終了すると表示されます。

+1

'Thread.Sleep()'ではなく、タイマーを使用します。睡眠を使うことは糸の無駄です。 –

+0

すごくおかげで、私は心のC#男ではなく、彼のコードを構築していました。 – Grambot

+0

彼らはJavaでタイマーを持っています:) –

5

私はこのようなタイマーを使用します。最初にいくつかのインスタンス変数。

private int _countDown = 30; // Seconds 
private Timer _timer; 

およびコンストラクタまたは負荷イベントで

_timer = new Timer(); 
_timer.Tick += new EventHandler(timer_Tick); 
_timer.Interval = 1000; 
_timer.Start(); 

そして最後にイベントハンドラ、これはすべての問題を扱うと同じようにあなたはまた、タイマーを使用することができます

void timer_Tick(object sender, EventArgs e) 
{ 
    _countDown--; 
    if (_countDown < 1) 
    { 
     _countDown = 30; 
    } 
    lblCountDown.Text = _countDown.ToString(); 
} 
1

UIロックのようなものです。 System.Windows.Forms.Timer -Timerを使用できます。 MSDNライブラリでは、そのサンプルを見つけることができます。

WinForms-Timerは、TimerスレッドとUIスレッド間の呼び出しも処理します。

- SeriTools

関連する問題