2011-02-02 8 views
2

私はWindowsアプリケーションを持っています。自動保存機能をバックグラウンド処理として実装しました。一定の時間間隔の後にタスクを実行するためのベストプラクティスは何ですか?

サンプルコード以下の通りです:

While(1) 
{ 
    Thread.Sleep(60000) // 1 minute sleep 
    DoAutoSaveAllControls(); 
} 

私はこれは悪い機能だと思います。私が間違っているなら、私を訂正してください。しかし、私はパフォーマンスを改善し、Sleepを実行せずに一定の時間間隔の後にこのタスクを実行したいと思います。 また、これはバックグラウンドプロセスで行うのが良いですか?

+0

また、この関連の質問を参照してください。[遅延実行のためのThread.sleepやタイマーを使用して比較](http://stackoverflow.com/questions/391621/compare-using-thread-sleep-and-timer-for -delayed-execution) –

答えて

4

もっと良い方法は、タイマーを使用することです。あなたは、この優れた記事から.NETフレームワークにおける様々な異なるタイマーを知ることができます:あなたはWinFormsのを使用している

http://msdn.microsoft.com/en-us/magazine/cc164015.aspx

ので、System.Windows.Forms.Timerはあなたのためだけの罰金となります。例えば

System.Windows.Forms.Timer tmrWindowsFormsTimer = new System.Windows.Forms.Timer(); 
tmrWindowsFormsTimer.Interval = TimeSpan.FromMinutes(1); 
tmrWindowsFormsTimer.Tick += new EventHandler(tmrWindowsFormsTimer_Tick); 
tmrWindowsFormsTimer.Start(); 


private void tmrWindowsFormsTimer_Tick(object sender, System.EventArgs e) { 
    tmrWindowsFormsTimer.Stop(); 
    DoAutoSaveAllControls(); 
} 

これは最初のダニ、効果的に火災ワンスタイマーの後にタイマーを停止します。

0

Thread.Sleepパフォーマンスにまったく影響しません。私にとっては大丈夫ですが、アプリケーションがおそらくUIスレッドのドキュメントを変更しているので、同時に変更を避けるために保存を積極的にする必要があります。この理由から、おそらく、BackGroundWorkerの代わりにTimerを使用するほうがよいでしょう。

+0

'while + sleep'の解決策は、スレッドを常に占有することによって少しパフォーマンスを傷つけます。クライアントではOK、サーバーアプリケーションでは受け入れられません。 –

+0

'Thread.Sleep'は多くの理由で悪い解決策です。 [興味深い関連する読書](http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx)。 –

+0

スリーピングスレッドはCPUを消費しません。励ますアイデアではありませんが、パフォーマンス漏れが間違っていると言っても –

0

あなたはそうです、それは実際にスレッドをうまく使用するものではありません。 Timerクラスを見てください。

0

私はあなたが(すでに変更があったかどうかを知っている)呼び出しコードから機能を保存する必要があると思います。したがって、スレッドを保存すると、呼び出し元のスレッドが保存するために何らかの変更が加えられたことを確実に知ることができます。

これはこの質問の回答ではなく、多分お勧めです。したがって、タイマーの内部からSaveを呼び出す場合は、まず変更が発生したかどうかを確認する必要があります。これを行うには、いくつかの追加変数が必要になります。これは、スレッドの動作とスレッドの保存に共通しています。作業スレッドが何かを変更した場合は、そのvarをtrueにトリガーします。保存するときに、varが真の場合、保存が必要です。保存した後、common varをfalseに変更します。

+1

これはおそらく私が今までに見た中で最も曖昧な答えです。だから、私は何かをする何らかの呼び出しコードから救うために何かをする必要がありますか? –

+0

ええ、私は同意します...あなたは何かをしたいと少し急いでいる場合は時々起こります。 –

0

あなたが一定の間隔後にそのプロセスを開始するためにSystem.Timers.Timerを使用することができ、サンプルスニペットをチェック

aTimer = new System.Timers.Timer(10000); 

    // Hook up the Elapsed event for the timer. 
    aTimer.Elapsed += new ElapsedEventHandler(YourHandlerMethod); 

    // Set the Interval to 2 seconds (2000 milliseconds). 
    aTimer.Interval = 2000; 
    aTimer.Enabled = true; 
2

well.Itがより自然に見えるし、観測を組み合わせることができますようあなたは、このための反応性Extenssionsを使用することができます。

var observable = Observable.Timer(
        TimeSpan.FromMinutes(1), 
        TimeSpan.FromMinutes(1)).Timestamp(); 

    using (observable.Subscribe())) 
    { 
     DoAutoSave(); 
    } 
関連する問題