2009-07-23 2 views
14

私はタイマーを1秒に1回、winformで調べるようにしています。これを行う方法のアドバイスを探すと、スレッドに関する負荷があります。スレッドについては気にしません。なぜなら、私がしようとしているのは、1分で60から0に値をカウントダウンして停止することだけだからです。私はこの問題を解決するためにクラウドコンピューティングに入る必要はないと思っていますが、私は実際にWebフォームのボディーなので、この問題で少し錆びています。誰もが例にWinformsタイマーのダミー

を私を指すことができますここで私は任意の助けをいただければ幸いです

private void button1_Click(object sender, EventArgs e) 
    { 
     this.timeLeft = 60; 
     this.label1.Visible = false; 
     this.button1.Visible = false; 
     gt = new Timer(); 
     gt.Tick += new EventHandler(CountDown); 
     gt.Interval = 1000; 
     gt.Start(); 
    } 

private void CountDown(object sender, EventArgs e) 
{ 
    do 
    { 
     this.TimeBar.Value = timeLeft;     
     this.timeLeft -= 1; 
    } while (this.timeLeft > 0); 
    if (this.TimeBar.Value > 0) return; 
    gt.Stop(); 
    this.label1.Visible = true; 
    this.button1.Visible = true; 
} 

を試みたものです。

答えて

8

何が起きているのかは、timeLeft変数を、タイマーの最初のティックでゼロになるまで減らしていることです。 do...whileループを取り出すと、基本的に動作する例が得られます。

ただし、Windowsフォームの作業を行うには、スレッドとそのUIにどのように影響するのかを知る必要があります。役に立たない例外や誤ったUIコンポーネントの話に慣れないと、すぐにここに戻ります。 Jon Skeetの優秀性はthreading seriesです。私は非常にそれをお勧めします。それはタイマーに専念するセクションを持っているので、あなたにいくつかのさらなる洞察を与えるかもしれません。

+0

カウントダウンが終了した後にタイマーを無効にすることを忘れないでください。そうしないと、負の数になります。 –

+0

ありがとう、ここではかなり遅いですが、もちろんループは必要ありません。 Skeet氏のスレッド文書へのリンクにも感謝します。 :) –

+0

@Martinho - Obligado、ええ、それも私を得た:) –

8

You は、winformsのタイマーを使用する場合はスレッディングが必要です。

ドロップページ上のTimerコントロール、名前を「タイマー」と次のコードを貼り付けます:

public MainForm() 
{ 
    InitializeComponent(); 

    timer.Interval = 1000; 
    timer.Start(); 

    timeLeft = 60; 
    timer.Tick += Timer_Tick; 

    // start things 
    label1.Hide(); 
    button1.Hide(); 
    timer.Start(); 

} 

public void Timer_Tick(object sender, EventArgs e) 
{ 
    timeLeft--; 

    if (timeLeft <= 0) { 
     timer.Stop(); 
     label1.Show(); 
     button1.Show(); 
    } 
} 

を私はあなたがウェビーの背景から来ている場合は、イベント駆動型のプログラミングは、おそらくものであると仮定デスクトップ上のものがどのようにプログラムされているかを理解したい場合は、まず読んでおく必要があります。

+0

ありがとう、ええスレッディングはちょうどノイズだった、私はそれを今ソートしましたが、私はまた、良い読書の指針を持っている。 –

2

イベントハンドラではループ処理を行いません。ハンドラは、タイマーごとに1回、1000ミリ秒ごとに呼び出されます。したがって、timeLeft変数を1回の呼び出しで減らしたい場合は、timeLeftがゼロになると全体がシャットダウンされます。

// untested 
private void CountDown(object sender, EventArgs e) 
{ 
    this.TimeBar.Value = timeLeft; 
    this.timeLeft--; 
    if (this.TimeBar.Value == 0) 
    { 
     gt.Stop(); 
     this.label1.Visible = true; 
     this.button1.Visible = true; 
    } 
} 
+0

おかげさまで、ちょっとした脳のフェードがありました。貧しいテレビのために、私の娘が使う小さなプロジェクトをやっていました。あなたのコードは、私が結局結んだものです。 –

3

アプリは一種のビジー状態の場合は別に(あたりjasonhの答えとして)ループを取り出すから、あなたのアプローチは少し不正確になる可能性があります。間隔はミリ秒単位で指定しますが、WinFormsタイマーの解像度は18msで、優先順位は非常に低く、メッセージループはタイマーを確認します。

したがって、StartTime(DateTime)値を保持し、それを使用してすべてのTimerイベントの残り時間を計算します。 1分に達するのにちょうど61チックが必要です。

+0

ええ、タイマーは約55ミリ秒正確です。それは本当に些細なことをしているだけなので、1分で+ -3秒が実行されますが、他のプロセスは銀行を壊すこともありません。おかげで:) –