2010-11-24 32 views
5

私はC#でWindowsサービスとしてQuartz.NETを実装しようとしています。私の仕事は、私がそれらを誘発することを期待したときに誘発していません...まったく、実際には、私が知る限りでは?Quartz.NET - ジョブは実行されませんか?

私の仕事のスケジュールは、「微妙に」実行された後の次の瞬間からも始まります。しかし、次の分が来ると、実際に何かが走っているかどうかは分からないようです。

ジョブ実行時にCLIウィンドウがジョブ実行時にポップアップ表示され、コンソール操作が表示されることが考えられます(私はさらにウィンドウが開かないようにするためにConsole.ReadKey()をそこに入れます)私はそれを見ることはできませんが)、私はスケジュールを伝えることができる限り、単にジョブを実行していません。

私はすべての時間がUTCであり、StartTimeUtcは自分のローカルコンピュータから+6時間のUTC時間に設定されていることに気付きましたが、Quartzスケジューラが実行を計算して私のTimeZone設定からの時間ですが、私はそれを確認する方法がない、または私のスケジュールが設定されている実際の時間を確認する方法はありません。

Common Loggingアセンブリを設定し、それを利用して自分のステータスを知るのに役立つと思いますが、私はまだそれをどのように処理したらよいのか分かりません。私はそれを作成したイベントログへの書き込みとは別に、Windowsサービス。

次のように私のWindowsサービス

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()関数の私のOnStart機能は次のとおりです。

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

あなたは私のACTUALスケジュール・アクティビティをトラブルシューティングする方法を見つけ出すことができた場合は、私はこれを私自身で解決できるかもしれません...?

答えて

0

感謝を..残念ながら、これを動作させることはできませんでしたが、 nのイベントログを私のジョブ実行関数に渡すと、毎分分のイベントログに期待どおりに書き込んだことがわかりました。

windowsサービス環境でConsole.WriteLine()Console.ReadKey() funcsは何もしないと思いますか?

注:彼らがサービスとしてではなく、コンソールウィンドウで何かをしますが、バックグラウンドで実行されている...

+1

私が正しく覚えていれば、Console.AnythingはWindowsサービスを爆破します。 –

0

トリガーの誤発火にはいくつか問題がありました。 I added a global trigger listenerは、ジョブの発砲に関連するイベントを捕捉し、問題をデバッグするために必要な情報を提供しました。

また、NLogをCommon.Loggingに接続してQuartzの内部ログを取得しました(私たちはSimple Logging Facadeを使用しているので、コンポーネントもここで設定されています)。ここで我々のアプリの設定だ、うまくいけば、それはあなたを開始ジャンプすることができます:Quartz.NETタスクで

<?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

、あなただけJobExecutionException例外を上げる必要があります。 Quartz.net- Lesson 3

Job.Execute(..)メソッドを最後に、 は、 IJob.Execute(..)メソッドのいくつかの詳細を通知する必要があります。 が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

+0

非常に真実。私はConsoleの使い方に気付かず、Windowsサービスではうまく動作しません。 –

+0

@keith - Windowsサービスはコンソールに出力できます。これに対話型アクセスを有効にする必要があります。 – Matt

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

デバッグ中にコンソールに切り替えることができます。 – Mrchief

0

あなたの仕事のコードプットで、オープンのVisual Studioを保つあなたの仕事をデバッグする場合:

System.Diagnostics.Debugger.Launch();

Visual Studioでデバッガに接続できるようになり、何が起こっているのかを確認できます。

また、共通のロギングを有効にしたい場合は、Windowsサービスですべて正常に動作しているため、メッセージを送信してください。

関連する問題