获取服务以在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();
}
}
}
答
我觉得你的问题的根源是,你根本无法安装以编程方式在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/
希望帮助
你为什么不把一个try/catch周围的一切,并记录异常? (我通常这样做:http://blog.smarx.com/posts/printf-here-in-the-cloud。)这比读代码和尝试猜测要容易很多。 – smarx
另外,当你在计算模拟器下本地运行它时它是否工作? – smarx
我只是将工作者角色分离成一个新的解决方案(与我的web角色分开),并获得更具体的错误消息。当我在本地运行它时,它说:“无法从命令行或调试器启动服务。首先必须安装Windows服务(使用installutil.exe),然后使用ServerExplorer,Windows服务管理工具或NET START命令启动。 – hughesdan