获取服务以在Azure工作者角色内部运行

问题描述:

我有一个需要作为工作者角色迁移到Azure的Windows服务。在我的Azure解决方案中,一切都很好。但是,当我上传所有内容时,只有网络角色开始。工作者角色实例在以下两种状态之间停滞不前,无法启动。获取服务以在Azure工作者角色内部运行

  • 等待角色开始...
  • 稳定作用...

由于实例启动失败,我怀疑我的问题在于我WorkerRole.cs代码的某个地方。下面你会发现这个代码。我还包含了与该问题相关的服务代码。我做错了什么?

这是我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); 
    } 

} 
} 

这是我的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

你为什么不把一个try/catch周围的一切,并记录异常? (我通常这样做:http://blog.smarx.com/posts/printf-here-in-the-cloud。)这比读代码和尝试猜测要容易很多。 – smarx

+0

另外,当你在计算模拟器下本地运行它时它是否工作? – smarx

+0

我只是将工作者角色分离成一个新的解决方案(与我的web角色分开),并获得更具体的错误消息。当我在本地运行它时,它说:“无法从命令行或调试器启动服务。首先必须安装Windows服务(使用installutil.exe),然后使用ServerExplorer,Windows服务管理工具或NET START命令启动。 – hughesdan

我觉得你的问题的根源是,你根本无法安装以编程方式在Azure角色中提供服务。您需要使用.cmd启动脚本和InstallUtil来正确安装该服务,然后才能从脚本或代码中启动它(认为从脚本开始往往是为了执行次序的原因)。

下面是关于如何做到这一点博客文章:http://blogs.msdn.com/b/golive/archive/2011/02/11/installing-a-windows-service-in-a-worker-role.aspx

这里的另一篇博客是需要一点点不同的方法(创建一个.net应用程序,执行安装,但同样为启动脚本的一部分): http://www.bondigeek.com/blog/2011/03/25/runninginstalling-a-windows-service-in-an-azure-web-role/

希望帮助