2014-08-29 14 views
1

我已經把代碼放在石英從 http://fssnip.net/ecQuartz.Net F#代碼運行腳本,但不是主要

成F#源文件中VS 2013年,但我把最後一行中的函數:

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()仍然有效(即時間被印刷每秒),並且調用start()從一個主方法不再作品。 我期望調用start()將不再起作用,不管它是從腳本還是源文件中調用。

如果有人能解釋爲什麼從腳本文件調用start()仍然有效,我將不勝感激。

回答

2

當你省略了()的型線,作業類型將不再有主構造。它仍然是一個類,它仍然實現了IJob,但是在代碼中沒有定義構造函數 - 在那種情況下,C#會添加一個默認的無參數變量,而F#則不會。忽略它不會使工作界面以任何方式 - 我想你可能是想做到這一點(使用對象表達式來定義接口的具體實例):

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

現在,我不知道知道Quartz在計劃工作時的工作細節,但很可能它會嘗試創建類的實例以調用接口方法 - 因爲構造函數已經失效,該嘗試失敗(我驚訝地發現它失敗了雖然默默地)。

這是您從主方法調用時看到的內容。

但是,當從FSI執行相同操作時,像Job類型這樣的類型會使用默認的無參數構造函數編譯。我不知道爲什麼這兩個環境之間的這種差異,以及它是故意還是錯誤(我假設後者)。

您可以通過致電typeof<Job>.GetConstructors()(來自System.Reflection)對您的類型進行驗證。主要和FSI的結果會有所不同。

+0

我在腳本和主函數中添加了typeof .GetConstructors()。在腳本中,typeof 返回[| Void .ctor()|]。在main中,它返回[||]。 – shing 2014-08-30 08:57:43

+0

以某種方式靜默失敗,作業在不同的處理線程上實例化,但會記錄錯誤。沒有啓用錯誤級別的日誌記錄通常會導致類似這樣的問題。我甚至看到人們在構造函數中做DB查詢可能會失敗...... – 2014-08-30 14:30:05

相關問題