2016-07-06 1 views
-1

残りの時間を表示している間に、指定した時間待機するにはどうすればよいですか?while句の条件は、どの時間間隔でチェックされていますか?

私は今、このようにそれを解決したが、これはそれを行うには本当に悪い方法であるような気がします:

//This is running in a BackgroundWorker: 

Stopwatch watch = new Stopwatch(); 
watch.Start(); 
while(watch.ElapsedMilliseconds != SecondsToWait * 1000) 
{ 
    TimeToNextRefresh = ((SecondsToWait * 1000) - watch.ElapsedMilliseconds)/1000; 
    Thread.Sleep(1); 
}     
watch.Stop(); 

だからここに私は条件(watch.ElapsedMilliseconds != SecondsToWait * 1000)はミリ秒ごとにチェックされていることを推測しています。

したがって、主な質問は次のとおりです。チェックされている間の条件は何時ですか?また、私が書いたコードをどのように改善しますか?

+2

は、Timerオブジェクトを使用します。このようなホットループを書くことは決して良い考えではありません。 'Thread.Sleep'は問題を解決しません。 –

+0

@CodyGray例を挙げてください。実行を一時停止したいだけです...タイマーでこれをどうやって行えますか? –

+0

実行を「一時停止」したいのはなぜですか?なぜそれが役に立つのでしょうか? –

答えて

2

ループ内のコードは何ですか?

たとえば、実際に長い/時間のかかるコードをwhileループに書くと、whileループまたはコースの各反復は、短い/速いコードしかないwhileループより長くなります。

while (true) { 
    Console.WriteLine("Hello"); 
} 

while (true) { 
    Console.Beep(5000); 
} 

Console.Beep(5000) 5秒かかり、Console.WriteLineのみがかかるため、ループが第二のものより速くなるしつつ、第1の各反復:

は、これら二つのwhileループを比較します1秒の数分の1。

whileループを使用して時間をカウントすることはできません。

これは、あなたが何をすべきかです:

System.Windows.Forms.Timerのインスタンスを作成し、ないSystem.Timers.TimerSystem.Threading.Timer。私は最初のものが最も有用である(他のものはより高度である)。

Timer timer = new Timer(); 
timer.Interval = 1000; // 1000 means 1000ms aka 1 second 
timer.Tick += TimerTicked; 
timer.Start(); 

今、コンパイラはTimerTickedが定義されていないことを伝える、それでは、その定義を手放すます:

private void TimerTicked(object sender, EventArgs e) { 

} 

は今、あなたはすべてのセットです。 TimerTickedのコードは1秒ごとに呼び出されます。

たとえば、10秒の時間を測定したいとします。 10秒後に何かしたい。だから、最初のクラスのレベルにsecondsLeftという変数を作成します。

int secondsLeft = 10; 

を今TimerTickedに、あなたは、それがある場合secondsLeftが0であるかどうかを確認したいことを何か他のもの、マイナスいずれかの操作を行います。

if (secondsLeft == 0) { 
    DoSomething(); 
} else { 
    secondsLeft--; 
} 

secondsLeftです!ラベルなどで表示することができます。タイマーを一時停止する

、単に

timer.Stop(); 
+0

'Timers.Timer' /' Threading.Timer'の何が問題なのですか?あなたがそれをお勧めしないように聞こえる。あなたは、あいまいさを導入せずにどちらを選択するかを明確に示すために 'var timer = new System.Windows.Forms.Timer();'と書くだけでよいでしょう。 Btw、wpfのwinformsは... [kek](http://www.urbandictionary.com/define.php?term=kek)です。 – Sinatr

+0

私は最初にこれらの3つのタイマーを見たとき、私はwinformsが最も使いやすいものを見つけました。スレッディングタイマーは本当に厄介です...私は 'Timers.Timer'を試しましたが、UIスレッドでイベントハンドラを実行していないようです。だから私はそれが気に入らなかったのです。私はこの回答を書いているときにOPがWPFを扱っていることを知らなかった。私が知っていても、OPは初心者のように思えるので、私はまだ答えを投稿します。私はwinformsタイマーがその直感のために初心者のために最も適していると思います。つまり、OPは経験が豊富なときに他の人を試すことができます。 @ Syinr – Sweeper

+0

はい、WinFormsアプリケーションでは、WinFormsタイマーを使用する必要があります。他のタイマーはすべて異なる目的のために設計されています。 WinFormsアプリケーションから作業するように設計されているため、より直感的です。直感的です。あなたがコンソールアプリケーションを持っているなら、WinFormsタイマーを使うのは直感的ではありません。実際には、まったく動作しません。 –

2

whileの状態が正確に確認される間隔は予測しにくいです。 Thread.Sleep(1);は、オペレーティングシステムに、スレッドをに少なくとも1秒間スリープさせたいと指示するだけです。 1ミリ秒。スレッドが正確に1ms後に再度アクティブになるという保証はありません。実際には、それ以上のことを確実にすることができます。スレッドは1ms後に再びスケジューリングされますが、CPUタイムスロットを取得するまでに遅延が発生します。

間隔あなたのループのためのが実際に残りの時間をどのように表示するかによって異なります。数秒しか表示しない場合は、1000ミリ秒ごとにテキストが変わりますが、ミリ秒ごとにその表示を更新するのはなぜですか?

このようなループは、おそらくそのようなものを実装するための良い方法ではありません。この方法は、Timerによって呼び出されるよう再度UIスレッド上で「あなたの表示を更新する」の部分を持っています

// this Timer will call TimerTick every 1000ms 
Timer timer = new Timer(TimerTick, null, 0, 1000); 

public void TimerTick(object sender) 
{ 
    // update your display 
} 

ハンドラを実装注:私はSystem.Threading.Timerをお勧めします別のスレッドで。

+0

私はWPFを使用しており、DataGridをリフレッシュしたい(毎分SQLからデータを取得する)。データを取得したら、CompletedEventでWorkerを再起動し、次のリフレッシュまでの残り時間を表示します。 –

+0

あなたの努力に感謝します。私は非常に多くの質問をして申し訳ありませんが、次のチックに残りの時間を得るための方法がありますか? –

+0

@ヌードなぜあなたはそれを望みますか?この 'Timer_Tick'は1000ms毎に呼び出されるようになりました(毎秒1回)。あなたの次の更新を得るまでの時間を計算するロジックはあなたのプロジェクト/コードを知らないのであなた次第です。この方法は1000msごとに(ただし数ナノ秒後に)正確には呼び出されませんが、秒を表示するのに十分です。 –

0

このコードは、実際に計算が1ミリ秒より長くかかる場合、実際には無限ループになります。

あなたはこのような単純なSystem.Winforms.Forms.Timerをご希望の動作を実現することができますが、以下の切り取ら:

private int tickCount = 0; 
    private int remaining = 10; 

    private void timer1_Tick(object sender, EventArgs e) 
    { 
     remaining--; 
     textBox1.Text = remaining.ToString(); 


    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 


     timer1.Interval = 1000; 
     timer1.Enabled = true; 
    } 

をこれを使用すると、10秒からカウントダウンすることができ、すべてはあなたがテキストボックスに書き込み、残りをチェック秒

関連する問題