5

I have a simple Azure Worker role running that performs a task every few seconds. Below is the code that accomplishes this.

    public override void Run()
    {
        try
        {
            while (true)
            {
                DoSomething();
                System.Threading.Thread.Sleep(3000);
            }

        }
        catch (Exception ex)
        {
            Log.Add(ex, true);
        }            
    }

What I'd like to do now is add a second task DoSomethingElse() that fires once and only once per day. I've thought of a couple of ways to accomplish this:

  1. Add a counter that calls the new task every nth loop
  2. Add conditional logic to the new task that compares the current time to a prescribed time of day
  3. Use some TBD scheduler library (such as Quartz.NET)

The first two solutions strike me as very brittle without additional code to deal with situations where the service is stopped and restarted. The third solution strikes me as potentially overkill.

My question is, what is the best practice for scheduling tasks at different intervals within an Azure Worker Role? I have a slight preference for sticking with straight .NET and not using a third-party library (though I'm not ruling it out).

Note, #3 above comes from this older question Recommend a C# Task Scheduling Library

Community
  • 1
  • 1
hughesdan
  • 3,019
  • 12
  • 57
  • 80

2 Answers2

2

The first two options are the simplest but they are brittle - especially in the cloud where roles can be recycled/load balanced etc... If the persistence is in memory or even disk based in the cloud, then it will be brittle.

Outside of other third party options, you could look at persisting the schedule and execution data into external storage (table services, sql azure, etc...). On a periodic timer, the worker role can query for the jobs that are due to be performed, record starting and then run the job. That also allows you to potentially scale out the number of worker roles since it's persistence is external.

This can get complicated in a hurry but if you keep it simple with frequency and recording run times, it can be fairly straight forward.

bryanmac
  • 38,941
  • 11
  • 91
  • 99
  • Let's say for the moment that I persist the execution data to a SQL Azure database. I could build a simple check into DoSomethingElse() that pings the database to determine when the task was last run. This would mean pinging the database to perform that check every 3 seconds. Is that a bad idea? It's a lot of unnecessary trips to the database. But then again the database server is unlikely to be strained by such trivial transactions. Thoughts? – hughesdan Nov 27 '11 at 20:40
1

Steve Marx wrote a nice couple of blog entries on how to build a task scheduler on Windows Azure using blob leases, I think you will find this very useful.

Yossi Dahan
  • 5,389
  • 2
  • 28
  • 50
  • He explains how to distribute the tasks to be scheduled. But he doesn't say anything about how the initial logic itself is triggered i.e. how does a worker role know "now" is the time to wake up and check if any tasks are scheduled in the table? Good article otehrwise – DeepSpace101 Jan 26 '13 at 01:15
  • as you noted, a worker role is essentially a program in an infinite loop. in it you would code the check as you wish - presumably run at a certain interval that suites you - every second, minute, hour, whatever and at each run check against a schedule database of sorts if anything needs doing. you will probably want to update that database with the last execution time and possibly result. – Yossi Dahan Jan 26 '13 at 18:27