Lucent Fox
Lucent Fox

Reputation: 1795

Windows Azure Worker Role, what to do with the main thread?

So we're setting up a worker role with windows azure and it's running at a very high cpu utilization. I think it has something to do with this section, but I'm not sure what to do about it. Each individual thread that gets started has its own sleep, but the main thread just runs in a while loop. Shouldn't there be a sleep in there or something?

public class WorkerRole : RoleEntryPoint
    {
        private List<ProcessBase> backgroundProcesses = new List<ProcessBase>();

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

            foreach (ProcessBase process in backgroundProcesses)
            {
                if (process.Active)
                {
                    Task.Factory.StartNew(process.Run, TaskCreationOptions.LongRunning);
                }
            }

            while (true) { }
        }

How about something like this, would this be appropriate?

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

            List<Task> TaskList = new List<Task>();

            foreach (ProcessBase process in backgroundProcesses)
            {
                if (process.Active)
                {
                    TaskList.Add(Task.Factory.StartNew(process.Run, TaskCreationOptions.LongRunning));
                }
            }

            Task.WaitAll(TaskList.ToArray());
            //while (true) {  }
        }

Upvotes: 2

Views: 1743

Answers (4)

Lucent Fox
Lucent Fox

Reputation: 1795

Just deployed this to production this morning after testing it last night on staging. Seems to be working great. CPU usage went down to .03% average for the background process down from 99.5% ...

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

            List<Task> TaskList = new List<Task>();

            foreach (ProcessBase process in backgroundProcesses)
            {
                if (process.Active)
                {
                    TaskList.Add(Task.Factory.StartNew(process.Run, TaskCreationOptions.LongRunning));
                }
            }

            Task.WaitAll(TaskList.ToArray());
            //while (true) {  }
        }

Upvotes: 0

sharptooth
sharptooth

Reputation: 170489

while loop with empty body will fully load the CPU core to which the thread is dispatched. That's bad idea - you burn CPU time for no good.

A better solution is to insert a Thread.Sleep() with a period ranging anywhere from 100 milliseconds to infinity - it won't matter much.

while( true ) {
    Thread.Sleep( /*anything > 100 */ );
}

Once you've got rid of the empty loop body you're unlikely to do any better than that - whatever you do in your loop the thread will be terminated anyway when the instance is stopped.

Upvotes: 1

Brian Reischl
Brian Reischl

Reputation: 7356

The while loop is probably causing your high CPU. It's basically an infinite busy-wait. Your second code sample should work fine, as long as the Tasks you're waiting on never exit. In my personal opinion the best solution is the one outlined in my answer here. If you don't like that, a simpler solution would be to add a Sleep() inside the loop. eg:

while(true){
    Thread.Sleep(10000);
}

Upvotes: 2

user94559
user94559

Reputation: 60143

Your change looks good to me. Sometimes I use Thread.Sleep(Timeout.Infinite).

Have you tested it? Does it reduce the CPU usage? It could be that the tasks themselves actually consume a lot of CPU. We don't know for sure yet that the while loop is the culprit.

Upvotes: 2

Related Questions