2012-03-05 4 views
9

私は、WindowsサービスではThread.Sleep(timeout)ではなくTimerを使用する方がよいことを理解しています。しかし、すべてのコード例で、私はAzureのワーカーを扱っていたインターネット上に見つけることができました。の代わりにThread.Sleep(timeout)が使用されています。 Visual Studioで労働者のプロジェクトテンプレートで提供.NETのAzureワーカーロールでThread.SleepまたはTimerを使用していますか?

でもデフォルトのコードが使用していますThread.Sleep

public class WorkerRole : RoleEntryPoint 
{ 
    public override void Run() 
    { 
     // This is a sample worker implementation. Replace with your logic. 
     Trace.WriteLine("$projectname$ entry point called", "Information"); 

     while (true) 
     { 
      Thread.Sleep(10000); 
      Trace.WriteLine("Working", "Information"); 
     } 
    } 
// ... 
} 

これまでのところ、私はまた私の労働者ではなく、本当に、なぜ理解せずThread.Sleepを使用してきました。だから私の質問は、なぜTimerではなく、AzureワーカーのロールでThread.Sleep(timeout)を使用していますか? WindowsサービスとAzureワーカーの違いは、このようなアプリケーションの考え方の違いにつながります。 Azureの労働者にTimerを使用するのは良いか悪いですか?

これまでのところ何も見つかりませんでしたので、これの基礎を説明するリソースへのリンクは、歓迎しています。

+0

これは実際にWindows Azure固有の質問ではありません。かなりのものになる[偉大なStackOverflow答え](http://stackoverflow.com/questions/2822441/system-timers-timer-threading-timer-vs-thread-with-whileloop-thread-sleep-for)さまざまなタイマーについて詳しく説明します。これはWindows Azure VMにも当てはまります。なぜなら、Windows Azure VMはWindows Server 2008 VMだからです。 –

+0

リンクをありがとう。面白いですが、私の質問に本当に答える気がしません。私はWindows AzureもVMだと理解していますが、それが_just_ VMだったのであれば、単にWindowsサービスを使用してみませんか?その場合、私の質問は、必要ではないでしょう。 – Guillaume

+0

ああ...まあ、あなたは確かにWindowsサービスを使用することができます。ただし、Windows AzureでWindowsサービスを使用するには、いくつかの作業が必要です。ここには何が関係しているかを示す[ブログ記事](http://blogs.msdn.com/b/mwasham/archive/2011/03/30/migrating-a-windows-service-to-windows-azure.aspx)があります。 Windows Azure WorkerまたはWeb Roleによって提供されるイベント内でコードを実行する方がはるかに簡単です。私の[これについての回答](http://serverfault.com/a/365054/99269)もServerFaultでご覧ください。 –

答えて

15

Thread.Sleep()ループの目的は、Run()メソッドを終了しないようにすることです。 Run()が終了すると、ワーカーが再起動します。私はあなたがタイマーでその目標を効果的に達成できるかどうかはわかりません。

ほとんどの場合、CPUは何もしないために1000ミリ秒ごとにそのスレッドを起動するために、少しの時間を無駄にしています。私はそれが重要だとは思っていませんが、それは私にも迷惑をかけました。私の解決策は、代わりにCancellationTokenを待つことでした。

public class WorkerRole : RoleEntryPoint { 
    CancellationTokenSource cancelSource = new CancellationTokenSource(); 

    public override void Run() 
    { 
     //do stuff 
     cancelSource.Token.WaitHandle.WaitOne(); 
    } 

    public override void OnStop() 
    { 
     cancelSource.Cancel(); 
    } 
} 

これは、ビジー待機時にCPU時間を浪費することなく、Run()メソッドが終了しないようにします。また、CancellationTokenをプログラムの他の場所で使用して、実行する必要のある他のシャットダウン操作を開始することもできます。

+0

私は、自分の 'WorkerRole'クラスの静的フィールドとして設定されたTimerを持っていて、そのElapsedイベントにメソッドが割り当てられていても、' Run() 'メソッドが処理された時点でスレッドは終了します? – Guillaume

+1

はい、それはドキュメントが言うものです。試してみると、あなたの役割が継続的に始動し、シャットダウンして再開することがよくわかります。 http://msdn.microsoft.com/en-us/library/windowsazure/microsoft.windowsazure.serviceruntime.roleentrypoint.run.aspx –

+2

「Thread.Sleep(Timeout.Infinity)」ソリューションは、 「WaitHandle」に?そのために、なぜManualResetEventを使用しないのですか?それはおそらく同じことです。 – casperOne

-2

Thread.Sleepはあなたのプロセッサの時間を無駄にしています。あなたのスレッドはブロックされていますが、CPUは何もしていませんが、他のスレッドで使用することはできません。私はAzureの価格モデルに精通していませんが、あなたのスレッドはそれを使用しているため、あなたはこの時間のために請求される可能性があります:)

したがってTimerは、

コード例では、簡略化のために通常Thread.Sleepが使用されています。

+0

M $は全く何もしないのに費用がかかりますか?素晴らしい - 私はそれを取り除くことができたらいいなあ! –

+7

@Martin - Microsoftはリソースの使用に対して料金を請求します。 VMを0%または100%CPUで1日中実行することができます。 1時間にコアごとに支払う。ちょうどホテルの部屋を借りるのと同じように:あなたはそれが党を投げているのか、それとも観光から離れているのかを支払う。 –

+0

さて、実際には、Thread.Sleepを使うコード例だけではありません。新しいWorkerプロジェクトを作成するときにWorkerテンプレートによって提供されるデフォルトのコードさえも、 'Thread.Sleep'を使用します。 – Guillaume

関連する問題