WorkerRole代码:
public class WorkerRole : RoleEntryPoint { #region Member variables private IWindsorContainer _container; private IJob[] _jobs; #endregion #region Methods public override bool OnStart() { ConfigureDiagnostics(); Trace.WriteLine("WorkerRole.OnStart()"); try { Initialize(); Trace.WriteLine("Resolving jobs..."); _jobs = _container.ResolveAll<IJob>(); StartJobs(); return base.OnStart(); } catch (Exception ex) { TraceUtil.TraceException(ex); throw; } finally { Trace.WriteLine("WorkerRole.OnStart - Complete"); Trace.Flush(); } } /// <summary> /// Sets up diagnostics. /// </summary> private void ConfigureDiagnostics() { DiagnosticMonitorConfiguration dmc = DiagnosticMonitor.GetDefaultInitialConfiguration(); dmc.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1); dmc.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose; DiagnosticMonitor.Start(Constants.DiagnosticsConnectionString,dmc); } /// <summary> /// Sets up the IoC container etc. /// </summary> private void Initialize() { Trace.WriteLine("WorkerRole.Initialize()"); try { Trace.WriteLine("Configuring AutoMapper..."); AutoMapperConfiguration.Configure(); Trace.WriteLine("Configuring Windsor..."); _container = new WindsorContainer(); Trace.WriteLine(string.Format("Installing assemblies from directory...{0}",Path.Combine(Environment.GetEnvironmentVariable(Constants.RoleRoot),Constants.AppRoot))); _container.Install(FromAssembly.InDirectory( new AssemblyFilter(Path.Combine(Environment.GetEnvironmentVariable(Constants.RoleRoot),Constants.AppRoot)))); Trace.WriteLine(string.Format("Setting the default connection limit...")); ServicePointManager.DefaultConnectionLimit = 12; } finally { Trace.WriteLine("WorkerRole.Initialize - Complete"); } } /// <summary> /// Starts all of the jobs. /// </summary> private void StartJobs() { Trace.WriteLine("WorkerRole.StartJobs()"); try { foreach (IJob job in _jobs) { job.Start(); } } finally { Trace.WriteLine("WorkerRole.StartJobs - Complete"); } } public override void OnStop() { Trace.WriteLine("WorkerRole.OnStop()"); try { foreach (IJob job in _jobs) { job.Stop(); } _container.Dispose(); } finally { Trace.WriteLine("WorkerRole.OnStop - Complete"); } } #endregion #region Private util classes public static class AutoMapperConfiguration { public static void Configure() { Mapper.Initialize(x => x.AddProfile<ModelProfile>()); } } #endregion }
TraceUtil代码:
public static class TraceUtil { public static void TraceException(Exception ex) { StringBuilder buffer = new StringBuilder(); while (ex != null) { buffer.AppendFormat("{0} : ",ex.GetType()); buffer.AppendLine(ex.Message); buffer.AppendLine(ex.StackTrace); ex = ex.InnerException; } Trace.TraceError(buffer.ToString()); } }
配置:
<?xml version="1.0" encoding="utf-8" ?> <configuration> ... <system.diagnostics> <trace autoflush="true"> <listeners> <add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener,Microsoft.WindowsAzure.Diagnostics,Version=1.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35" name="AzureDiagnostics"> <filter type="" /> </add> </listeners> </trace> </system.diagnostics> </configuration>
一旦工作人员开始,如果我查看WADLogsTable,我看到的只有“WorkerRole.OnStart()”,没有别的!
关于什么问题可能或如何解决这个问题的任何想法将不胜感激.
更新:如果我停止角色,我也看不到OnStop()方法的任何调试语句.
更新:我的诊断程序必须配置不正确.我以为我在本地调试时看到我的调试正确显示,但事实证明我不是.我看到输出窗口中的所有内容,但我看不到存储表中的所有内容.我正在开发中看到以下条目:
WorkerRole.OnStart() WorkerRole.Initialize() Configuring AutoMapper...
我意识到跟踪输出只是定期上传,但是我已经等了5分钟左右,所以我觉得这应该足够长了,因为我设置了1分钟.
更新:根据@kwill在注释部分的建议,我尝试添加一个文件跟踪侦听器,如下所示:
<system.diagnostics> <trace autoflush="true"> <listeners> <add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener,PublicKeyToken=31bf3856ad364e35" name="AzureDiagnostics"> </add> <add name="File" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\TextWriterOutput.log" /> </listeners> </trace> </system.diagnostics>
这在我的开发环境中工作正常,似乎更可靠,并且我得到了我期望的所有调试.然而,当我部署它进行暂存时,TextWriterOutput.log文件甚至没有创建!
我真的需要一个可靠的方法来调试我的工作角色,以便我可以解决最终的问题,这是我的工作不工作 – 在这一点上,我仍然不知道他们甚至尝试做,因为我不能得到任何调试!
更新:我很确定大多数人建议的缺失的dll想法不是问题.为了希望证明这一点,我已经覆盖了如下所示的运行方式,我看到“Heartbeat …”调试出来了.在我看来,诊断功能或至少我配置的功能是不可靠的,这是阻止我调查为什么我的工作没有运行.
public override void Run() { Trace.WriteLine("LearningMiles.JobProcessor.WorkerRole.Run()","Information"); try { while (true) { Thread.Sleep(10000); Trace.WriteLine("Heartbeat...","Verbose"); } } catch (Exception ex) { TraceUtil.TraceException(ex); throw; } finally { Trace.WriteLine("LearningMiles.JobProcessor.WorkerRole.Run() - Complete","Information"); } }
更新:我现在已经在Windows Azure MSDN forum上发贴了这个问题.
更新:正如建议在评论中,我现在尝试删除所有“有用的”代码.在开发中,这导致所有的调试都被输出.然后,我尝试只是删除对AutomapperConfiguration.Configure()的调用,因为之前我在该调用后看不到任何内容.这导致一些跟踪声明不再出现.不过重要的是,我看到了我在“工作”中所发表的痕迹.由于我最终想要解决的是不运行的作业,所以我将该版本的代码部署到分段,但是我只看到OnStart()跟踪和“heartbeat”跟踪.我不认为这真的有帮助,但也许会给人一些想法.
一些事情要尝试:
>从Visual Studio手动“打包”您的部署,并仔细查看构建输出.很多时候,VS会抓住你的缺失的程序集,并告诉你(不幸的是作为一个警告,而不是一个错误)你缺少一些东西.>如果输出中看不到任何东西看起来很明显,请查看cspkg文件本身(记住它只是一个ZIP文件,其中包含更多ZIP文件),并确保您的应用程序/角色需要的任何引用的程序集都在那里.或者,连接到VM并检查这些程序集的审批.>您可能可以在VM的事件日志中找到一个条目,显示您的应用程序无法加载程序集.