Getting a Service to Run Inside of an Azure Worker Role
Asked Answered
A

1

10

I have a windows service that I need to migrate to onto Azure as a Worker Role. Everything builds fine in my Azure solution. However, when I upload everything only the web role starts. The worker role instance gets stuck cycling between the following two statuses without ever starting.

  • Waiting for the role to start...
  • Stabilizing role...

Since the instance is failing to start I suspect my problem lies somewhere in my WorkerRole.cs code. Below you'll find that code. I've also included the code for the service in case it's relevant to the question. What did I do wrong?

This is my WorkerRole.cs file:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
using System.ServiceProcess;

namespace SBMWorker
{
public class WorkerRole : RoleEntryPoint
{

    public override void Run()
    {
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] 
        { 
            new Service1() 
        };
        ServiceBase.Run(ServicesToRun);

        //Thread.Sleep(Timeout.Infinite);
    }

}
}

This is my Service1.cs code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using Lesnikowski.Mail;

namespace SBMWorker

{
public partial class Service1 : ServiceBase
{
    private System.Timers.Timer mainTimer;

    public Service1()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        try
        {
            // config the timer interval
            mainTimer = new System.Timers.Timer(foo.Framework.Configuration.SecondsToWaitBeforeCheckingForEmailsToProcess * 1000);
            // handling
            mainTimer.Elapsed += new System.Timers.ElapsedEventHandler(mainTimer_Elapsed);
            // startup the timer.  
            mainTimer.Start();
            // log that we started
            foo.Framework.Log.Add(foo.Framework.Log.Types.info, "SERVICE STARTED");
       }
        catch (Exception ex)
        {
            try
            {
                foo.Framework.Log.Add(ex, true);
            }
            catch{throw;}

            // make sure the throw this so the service show as stopped ... we dont want this service just hanging here like
            // its running, but really just doing nothing at all
            throw;
        }
    }

    protected override void OnStop()
    {
        if (mainTimer != null)
        {
            mainTimer.Stop();
            mainTimer = null;
        }
        // log that we stopped
        foo.Framework.Log.Add(foo.Framework.Log.Types.info, "SERVICE STOPPED"); 
    }

    void mainTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        mainTimer.Stop();

        bool runCode = true;

        if (runCode)
        {
            try
            {
                // call processing
                foo.Framework.EmailPackageUpdating.ProcessEmails();
            }
            catch(Exception ex)
            {
                try
                {
                    // handle error 
                    foo.Framework.Log.Add(ex, false);
                }
                catch { throw; }
            }
        }

        mainTimer.Start();
    }
}
}
Apartment answered 11/8, 2011 at 21:14 Comment(8)
Why don't you put a try/catch around everything and log the exception? (I usually do it this way: blog.smarx.com/posts/printf-here-in-the-cloud.) That would be a lot easier to debug than reading the code and trying to guess.Thrilling
Also, does it work when you run it locally under the compute emulator?Thrilling
I just separated the worker role into a new solution (separate from my web role) and am getting a more specific error message. When I run it locally it says "Cannot start service from the command line or a debugger. A Windows Service must first be installed (using installutil.exe) and then started with the ServerExplorer, Windows Services Administrative tool or the NET START command."Apartment
Oh, well maybe what it says is true. Does this work in a regular console application (forget Windows Azure for now)?Thrilling
It works as a windows service if you install it on a server. I wasn't the one who wrote it but I'm trying to repurpose it as a worker.Apartment
Yes, but I mean does your method of new-ing it up and calling Run() work? I'm wondering if the issue has to do with Windows Azure or if it's just the technique (trying to run a service without actually installing it as a service) that's problematic.Thrilling
I simplified things a bit and can confirm that it runs locally. Basically I'm just calling public override void Run() { Thread.Sleep(10000); foo.Framework.EmailPackageUpdating.ProcessEmails(); }. However, it just hangs when I publish it to Azure.Apartment
...By "hangs" I mean the role doesn't start.Apartment
M
6

I think the root of your problem is that you basically can't install a service programmatically in Azure roles. You need to use a .cmd startup script and the InstallUtil to properly install the service then you can start it from the script or from your code (think from the script is often preferred for order-of-execution reasons).

Here's a blog post on how to do it: http://blogs.msdn.com/b/golive/archive/2011/02/11/installing-a-windows-service-in-a-worker-role.aspx

Here's another blog post that takes a little different approach (creating a .Net app that executes the installation, but again as part of the startup script): http://www.bondigeek.com/blog/2011/03/25/runninginstalling-a-windows-service-in-an-azure-web-role/

Hope that helps

Maccabees answered 14/8, 2011 at 20:10 Comment(1)
For anyone like me trying to find these linked articles from old blogs, Microsoft has redirected everything to a A-Z list of document archives. You'll find one of the links here: learn.microsoft.com/en-us/archive/blogs/golive/…Dehumidify

© 2022 - 2024 — McMap. All rights reserved.