Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Thread.Sleep or Timer in Azure worker role in .NET?

I understand that in a Windows service, it is better to use Timer rather than Thread.Sleep(timeout). However, in all code examples I could find on the Internet that were handling Azure workers, it is Thread.Sleep(timeout) which is used instead of Timer.

Even the default code provided in the Worker project template in Visual Studio uses a 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");
        }
    }
// ...
}

So far, I've been also using Thread.Sleep in my workers but without really understanding why. So my question is, why using Thread.Sleep(timeout) in Azure worker role rather than Timer? What is the difference between Windows service and Azure worker that leads to this difference in how we are supposed to conceive this kind of application? Is it good or bad to use Timer in Azure workers?

Any explanation with links to some resources explaining the fundamentals of this is welcome as I couldn't find anything so far.

like image 428
Guillaume Avatar asked Mar 05 '12 04:03

Guillaume


1 Answers

The purpose of the Thread.Sleep() loop is to keep the Run() method from exiting. If Run() exits, then your worker will restart. I don't know that you could accomplish that goal effectively with a Timer.

Most likely your CPU is wasting some tiny amount of time to wake up that thread every 1000 msecs in order to do nothing. I doubt it's significant, but it bugged me too. My solution was to wait on a CancellationToken instead.

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

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

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

This keeps the Run() method from exiting without wasting CPU time on busy waiting. You can also use the CancellationToken elsewhere in your program to initiate any other shutdown operations you may need to perform.

like image 122
Brian Reischl Avatar answered Oct 12 '22 00:10

Brian Reischl