2011-08-11 9 views
10

Tengo un servicio de Windows que necesito migrar a Azure como una función de trabajador. Todo se desarrolla bien en mi solución de Azure. Sin embargo, cuando cargo todo, solo comienza la función web. La instancia de rol de trabajador se bloquea al pedalear entre los dos estados siguientes sin iniciar nunca.Obtener un servicio para ejecutar dentro de una función de trabajador de Azure

  • Esperando el papel para iniciar ...
  • papel estabilizador ...

Dado que la instancia no se inicia sospecho que mi problema se encuentra en algún lugar de mi código WorkerRole.cs. A continuación encontrará ese código. También incluí el código para el servicio en caso de que sea relevante para la pregunta. ¿Qué hice mal?

Este es mi archivo WorkerRole.cs:

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); 
    } 

} 
} 

Este es mi código Service1.cs:

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(); 
    } 
} 
} 
+0

¿Por qué no poner un try/catch alrededor de todo y log la excepción? (Normalmente lo hago de esta manera: http://blog.smarx.com/posts/printf-here-in-the-cloud.) Eso sería mucho más fácil de depurar que leer el código y tratar de adivinar. – smarx

+0

Además, ¿funciona cuando lo ejecuta localmente en el emulador de cómputo? – smarx

+0

Acabo de separar la función de trabajador en una nueva solución (separada de mi función web) y recibo un mensaje de error más específico. Cuando lo ejecuto localmente dice "No se puede iniciar el servicio desde la línea de comandos o un depurador. Primero se debe instalar un servicio de Windows (utilizando installutil.exe) y luego se inició con ServerExplorer, la herramienta administrativa de servicios de Windows o el comando NET START". – hughesdan

Respuesta

6

creo que la raíz de su problema es que, básicamente, no puede instalar una servicio programáticamente en roles de Azure. Necesita utilizar un script de inicio .cmd y InstallUtil para instalar el servicio correctamente, luego puede iniciarlo desde el script o desde su código (a menudo se prefiere pensar en el script por razones de orden de ejecución).

Aquí hay un post sobre cómo hacerlo: http://blogs.msdn.com/b/golive/archive/2011/02/11/installing-a-windows-service-in-a-worker-role.aspx

Aquí hay otra entrada de blog que tiene un enfoque un poco diferente (la creación de una aplicación .Net que ejecuta la instalación, pero una vez más como parte de la secuencia de comandos de inicio): http://www.bondigeek.com/blog/2011/03/25/runninginstalling-a-windows-service-in-an-azure-web-role/

Esperamos que ayuda

Cuestiones relacionadas