2017-02-18 9 views
0

私は拍/分で私の心拍数のレートでConsole.Beepを生成するはずのタイマーを持っています。私は私のC#タイマーでTimer.Intervalを計算するには、次の簡単な数式を使用しています:私はウェアラブルから私の心拍数を読んでいますリセットすることなくタイマーの間隔を変更できますか?

ServerVarValues = new ws ServerVarValues(); 
    this.timerHeartBeatSound = new System.Windows.Forms.Timer(this.components); 

    public class ServerVarValues 
    { 
     public int HR; 
     public DateTime LastHRUpdate; 
     public int SpO2; 
     public DateTime LastO2Update; 
     public double Temperature; 
     public DateTime LastTempUpdate; 
    } 

//... I plug in my heart rate to calculate my new timer interval...  
int tVal = (int)Math.Round((ws.HR/60.0) * 1000,0); 
timerHeartBeatSound.Interval = tVal; 

// and with the new interval, the timer generates a Tick Event that runs this 
    private void PlayHeartBeatSound(object sender, EventArgs e) 
    { 
     Console.Beep(); 
    } 

。問題は、自分のHRが変更されるたびに、タイマーの間隔を変更するとタイマーがリセットされることです。こうして、滑らかな変化する心拍数の代わりにしゃっくりが頻繁に聞こえます。

心拍数が変わるたびにタイマーをリセットしないようにするにはどうすればよいですか?

+2

.NETにはいくつかのタイマークラスがあります。どちらを使用していても、レートの変更に常に対応することは可能です。しかし、いくつかのタイマークラスは、他のタイマークラスに比べてより順応性があります。文脈によっては、実際のタイマーではなくループ内で 'Task.Delay()'を使用し、新しいデータを受け取るときに遅延値を非同期的に更新する方が望ましいことがあります。あなたがやろうとしていることを正確に示し、問題の修正に問題がある特定の問題を再現する、良い[mcve]を提供してください。 –

+0

こんにちはPeter - コードは実際にあなたが見るものです。私はビジュアルスタジオでタイマーを設定し、タイマー間隔を渡して有効にします。 tickイベントでは、Console.Beepを呼び出します。私が望まないのは、心拍数が変化するので、時間間隔を変えるたびに、タイマーをリセットすることです。私は、ビジュアルスタジオタイマーが理想的なものではないことを暗示していると思います。代わりに他のクラスを見てください。 – LeoM

+2

_ "コードは本当にあなたが見ているもの" _ - 本当ですか? _anything_を追加せずに上記のプログラムをコンパイルできますか? 'tVal'や' timerHeartBeatSound'変数や 'ws'の宣言ではなく、' class'とメソッド宣言にコードを入れることに気をつけませんか?先ほどお話した[mcve]の記事をお読みください。そのページの一番下にリンクされている記事を含む(さらには特に)[ask]も参照してください。 Stack Overflowに関するヘルプが必要な場合は、良い質問を投稿する方法を学ぶ必要があります。あなたは今それをやっていません。 –

答えて

0

「ASecond」の代わりに、現在の心拍数に対応するミリ秒数を使用する以外は、次のように試してください。これは、現在のレートに基づいて次のビートまでのミリ秒数を再計算し、ビートごとに行います。私はそれがよりスムーズだと思います。

DateTime LastTime = DateTime.Now; 

... 

DateTime NextTime = LastTime + ASecond; 
// Just in case we have gone past the next time (perhaps you put the system to sleep?) 
if (DateTime.Now > NextTime) 
    NextTime = DateTime.Now + ASecond; 
TimeSpan Duration = NextTime - DateTime.Now; 
LastTime = NextTime; 
timer1.Interval = (int)Duration.TotalMilliseconds; 
+0

上記のハンスの答えを参照してください。彼はそれを釘付けにした! – LeoM

+0

あなたは私を試しましたか?おそらくそうではありません。 – user34660

2

はい、これは仕様です。 Intervalプロパティを変更しても同じではない場合、Timerは自動的にリセットされます。この動作は変更できません。

だから何をする必要があります更新間隔です。次のチックが起こるまではない。それはうまくいく、心拍は十分に速く起こる。

public class ServerVarValues { 
    public int NextInterval; 
    // etc... 
} 

そして、あなたは、タイマーを起動したり、心拍値を更新したときに、それを初期化します:

... 
int tVal = (int)Math.Round((ws.HR/60.0) * 1000,0); 
if (timerHeartBeatSound.Enabled) ws.NextInterval = tval; 
else { 
    ws.NextInterval = 0; 
    timerHeartBeatSound.Interval = tval; 
} 

そしてTickイベントハンドラで、あなたが持っているかどうかを確認する必要があるあなたは、別の変数が必要になります新しいインターバルを有効にする:

private void PlayHeartBeatSound(object sender, EventArgs e) 
{ 
    if (ws.NextInterval != 0) timerHeartBeatSound.Interval = ws.NextInterval; 
    ws.NextInterval = 0; 
    Console.Beep(); 
} 
+0

あなたの答えは「箱の外で考えている」の完璧な例です!私はちょうどあなたのアイデアを試して、エレガントに動作します! – LeoM

+0

@Hans Passant、私の問題は何ですか?私はみんなの時間を無駄にしたと思う。 – user34660

+1

通常、SOユーザーは完全なソリューションを好むので、もっと使いこなすことができます。彼は私の答えを受け入れなかったかもしれないので、多分それをあまり読みすぎてはいけません。 –

関連する問題