2010-11-24 113 views
5

我试图在C#中将Quartz.NET作为Windows服务来实现。据我所知,我的工作并没有触发,实际上,我希望他们能够触发......实际上,Quartz.NET - 作业不运行?

我的“我的工作”计划在运行“分钟”后的下一分钟即开始运行。但是,当下一分钟到来时,我似乎无法分辨是否有任何实际运行。

我会假设当我的作业运行时,一个CLI窗口会在作业执行时弹出,并且控制台操作将可见,(我甚至在其中放置了一个Console.ReadKey()以确保窗口不打开和关闭如此快速我看不到它),但据我所知,时间表根本就没有执行任务。

我注意到,所有的时间都在UTC,那StartTimeUtc将被设置为UTC时间是从我的本地计算机时间6小时,但我也将认为Quartz调度处理,通过计算执行时间从我的TimeZone设置开始,但我无法确定这一点,或确认实际时间是否符合我的日程安排。

我想有一些方法来建立共同的测井组件,并利用它来帮助我知道我的身份是什么,但我还没有搞清楚如何处理做,以使日志任何种类的从反馈我Windows服务,除了写入我为它创建的事件日志。

我的我的Windows服务的OnStart功能

protected override void OnStart(string[] args) 
    { 
     eventLog.WriteEntry("--- STARTING eLoyalty Scheduler Service ---"); 

     // construct a scheduler factory 
     ISchedulerFactory schedFact = new StdSchedulerFactory(); 

     // get a scheduler 
     IScheduler sched = schedFact.GetScheduler(); 

     // construct job info 
     JobDetail jobDetail = new JobDetail("eLoyaltySchedulerService", null, typeof(PortalSchedulerJob)); 
     jobDetail.JobDataMap["jobSays"] = "eLoyalty Scheduler Service Executing!"; 
     jobDetail.JobDataMap["myStateData"] = new ArrayList(); 

     // fire every minute 
     Trigger trigger = TriggerUtils.MakeMinutelyTrigger(); 

     // start on the next even minute 
     trigger.StartTimeUtc = TriggerUtils.GetEvenMinuteDate(DateTime.UtcNow); 

     // name it 
     trigger.Name = "NextEvenMinute"; 

     // schedule it 
     sched.ScheduleJob(jobDetail, trigger); 

     // start the schedule 
     sched.Start(); 

     eventLog.WriteEntry("--- STARTED eLoyalty Scheduler Service ---"); 
    } 

我的工作的execute()函数如下:

public void Execute(JobExecutionContext context) 
    { 
     try 
     { 
      string instName = context.JobDetail.Name; 
      string instGroup = context.JobDetail.Group; 
      JobDataMap dataMap = context.MergedJobDataMap; 
      string jobSays = dataMap.GetString("jobSays"); 
      ArrayList state = (ArrayList)dataMap["myStateData"]; 
      state.Add(DateTime.UtcNow); 

      Console.WriteLine("Instance {0} of PortalSchedulerJob says: {1} @ {2}", instName, jobSays, DateTime.UtcNow); 
      Console.ReadKey(); 
     } 
     catch (JobExecutionException Ex) 
     { 
      throw Ex; 
     } 
    } 

如果你能帮助我弄清楚如何解决我的实际计划活动,我可以自己解决这个问题......?

回答

0

感谢您的输入大家.. 。不幸的是,我不能得到任何这样的工作,但是当我添加一个n事件记录器到我的作业执行功能,我发现它按预期在分钟内每分钟写入事件日志。

我猜Console.WriteLine()Console.ReadKey() funcs在Windows服务环境中什么都不做?

注意:他们做一些事情,但在后台运行的服务,而不是在控制台窗口...

0

我们在触发器失火时遇到了一些问题。捕获与作业相关的事件,并提供调试问题所需的信息。

我们还通过Common.Logging连接了NLog,以获取Quartz的内部日志(您可能会注意到我们自己使用了Simple Logging Facade,因此此处也配置了组件)。这是我们的应用程序配置,希望能够迅速启动你:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <configSections> 
     <section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" /> 
     <section name="slf" type="Slf.Config.SlfConfigurationSection, slf"/> 
     <sectionGroup name="common"> 
      <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" /> 
     </sectionGroup> 
    </configSections> 


    <quartz> 
     <add key="quartz.threadPool.threadCount" value="20" /> 
     <add key="quartz.jobStore.misfireThreshold" value="420000" /><!-- 7 minutes --> 
    </quartz> 


    <slf> 
     <factories> 
      <factory name="nlog" type="SLF.NLogFacade.NLogLoggerFactory, SLF.NLogFacade"/> 
     </factories> 

     <loggers> 
      <logger factory="nlog"/> 
     </loggers> 
    </slf> 

    <common> 
     <logging> 
      <factoryAdapter type="Common.Logging.NLog.NLogLoggerFactoryAdapter, Common.Logging.NLog"> 
       <arg key="configType" value="FILE" /> 
       <arg key="configFile" value="~/NLog.config" /> 
      </factoryAdapter> 
     </logging> 
    </common> 

</configuration> 
8

在Quartz.NET的任务,你必须只提高JobExecutionException例外: Quartz.net- Lesson 3

的Job.Execute(..)方法最后,我们 需要通知您一些 IJob.Execute(..)方法的细节。只有 类型的异常允许 从执行方法中抛出的是 JobExecutionException。由于 这一点,您通常应该用执行方法 的“try-catch”块封装 的全部内容。你应该 也花一些时间看 文档的 JobExecutionException,因为你的工作可以 使用它提供的调度 各种指令为你想怎么 被处理的异常。

相反的:

catch (JobExecutionException Ex) 
{ 
    throw Ex; 
} 

做这样的事情:

catch (Exception err) 
{ 
    // Only allow JobExecutionException exceptions to be thrown... 
    throw new Quartz.JobExecutionException(err); 
} 

然后,您可以集中处理异常:

_globalJobListener = new GlobalJobListener(); 
sched.AddGlobalJobListener(_globalJobListener); 


public class GlobalJobListener : Quartz.IJobListener 
{ 
    public GlobalJobListener() 
    { 
    } 

    public virtual string Name 
    { 
     get { return "MainJobListener"; } 
    } 

    public virtual void JobToBeExecuted(JobExecutionContext context) 
    {  
    } 

    public virtual void JobWasExecuted(JobExecutionContext inContext, JobExecutionException inException) 
    { 
     if (inException != null) 
     { 
      // Log/handle error here 
     } 
    } 


    public virtual void JobExecutionVetoed(JobExecutionContext inContext) 
    { 

    } 
} 
+0

这是有帮助的,但不是这个特定问题的答案! :) – Rimer 2010-12-09 05:42:01

+0

非常真实。被抓到异常处理的东西,我甚至没有注意到你使用控制台 - 这肯定不会在Windows服务中工作! – 2010-12-09 06:33:49

+0

@keith - Windows服务可以输出到控制台。您需要为此启用交互式访问。 – Matt 2015-07-05 02:00:40

2

你总是可以在控制台中运行的Windows服务,当您正在调试:

static class Program 
{ 
    static void Main() 
    { 
     var servicesToRun = new ServiceBase[] 
      { 
       new CassetteDeckService() 
      }; 

     if (Environment.UserInteractive) 
     { 
      var type = typeof(ServiceBase); 
      const BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic; 
      var method = type.GetMethod("OnStart", flags); 

      foreach (var service in servicesToRun) 
      { 
       method.Invoke(service, new object[] { null }); 
      } 

      Console.WriteLine("Service Started!"); 
      Console.ReadLine(); 

      method = type.GetMethod("OnStop", flags); 

      foreach (var service in servicesToRun) 
      { 
       method.Invoke(service, null); 
      } 
      Environment.Exit(0); 
     } 
     else 
     { 
      ServiceBase.Run(servicesToRun); 
     } 
    } 
} 

只要确保在Windows服务项目的属性中将应用程序类型更改为控制台应用程序(当它不以交互模式运行时,这不会影响其作为Windows服务运行)。

0

,如果你想调试你的工作,保持视觉工作室开放,在你的工作代码放:

System.Diagnostics.Debugger.Launch();

这将允许您附加到Visual Studio中的调试器,你可以看到发生了什么。

或者,如果你想得到常见的日志记录工作,给我一条消息,因为我已经在我的Windows服务中正常工作。