Quartz.Net F#代码在脚本中运行,但不在main中运行

时间:2014-08-29 19:52:50

标签: f# quartz.net

我把代码放在Quartz上 http://fssnip.net/ec

进入VS 2013中的F#源文件。但我将最后一行放入函数中:

let start():unit=
    scheduler.ScheduleJob(job, trigger) |> ignore

从脚本或主方法调用start()时,它可以正常工作。

但是当我改变了

type Job () =
  interface IJob with
     member x.Execute(context: IJobExecutionContext) =
     Console.WriteLine(DateTime.Now)

// omit the (), so that Job is an interface
type Job =
  interface IJob with
     member x.Execute(context: IJobExecutionContext) =
     Console.WriteLine(DateTime.Now)

调用start()仍然有效(即每秒打印一次),并且从main方法调用start()不再有效。 我希望无论从脚本或源文件中调用它,调用start()都将不再有效。

如果有人能解释为什么从脚本文件中调用start()仍然有效,我将不胜感激。

1 个答案:

答案 0 :(得分:2)

当省略类型行中的()时,作业类型不再具有主构造函数。它仍然是一个类,它仍然实现了IJob,但是代码中没有定义构造函数 - 在这种情况下C#会添加一个默认的无参数,F#不会。省略它不会以任何方式使Job成为一个接口 - 我想您可能想要这样做(使用对象表达式来定义接口的具体实例):

 let job = 
     { new IJob with
          member this.Execute ...
        }

现在,我不知道Quartz在安排作业时所做的细节,但很可能它会尝试创建类的实例以调用接口方法 - 因为构造函数已经消失,那个尝试失败了(我很惊讶它虽然无声地失败了。)

这是您在使用main方法调用时所看到的。

但是,当从FSI执行相同操作时,类似Job类型的类型将使用默认的无参数构造函数进行编译。我不知道为什么这两种环境之间的差异,以及它是故意的还是一个bug(我假设后者)。

您可以在类型上调用typeof<Job>.GetConstructors()(来自System.Reflection)进行验证。主要和FSI的结果会有所不同。