Using Thread.Sleep or Timer in Azure worker role i

2019-01-25 10:20发布

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.

2条回答
Juvenile、少年°
2楼-- · 2019-01-25 10:31

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.

查看更多
看我几分像从前
3楼-- · 2019-01-25 10:50

Thread.Sleep is literally waste of your processor's time. Your thread is blocked and though CPU is doing nothing it cannot be used by other threads. I am not familiar with pricing model of Azure, but you could be potentially charged for this time, because your thread used it :)

So Timer should always be used for any kind of pause.

Code examples usually use Thread.Sleep for the simplicity.

查看更多
登录 后发表回答