2012-06-29 57 views
3

我需要您的建議來安排MVC3 Webapp中的任務。使用Quartz.NET的MVC3 webapp任務調度

我的任務是爲webapp中的不同服務創建一些通用調度程序,以便以後在開發中使用。例如,我們有一些用戶可以隨時安排的可用任務。

我不想重新發明輪子,並找到可用於創建調度程序的Quartz.Net庫。我知道這是不是一個好主意,主持調度內部Web應用程序原因Web服務器可以回收應用程序池等,所以我決定在Windows服務中使用它,然後使用Quartz.NET遠程處理功能來觸發我內部的任務Web應用程序。

但我發現了一些問題。糾正我,如果我錯了,但是當我試圖使用Quartz.NET遠程處理它運行Windows服務進程內的作業,這意味着它需要知道我的web應用程序內的所有類型,所以所有程序集的webapp應該引用它,我需要另一個數據庫配置文件等,所以如果我寫新的工作類,我不能輕鬆地安排它,我需要停止服務,並更新它的庫,所以這不是非常通用的方法。

我找不到Quartz.NET只能根據它的接口運行作業的任何信息。

所以我想出了一個想法,寫我自己的調度程序,它將被託管在Windows服務中,並且將有一些IJob接口將在webapp中實現。我還將使用IPC通道使用.Net遠程處理。 因此,webapp會像.Net Remoting Server一樣,當我想添加一些新的工作然後安排它時,我只需要編寫實現IJob接口的新工作。 我會在這種情況下,註冊爲

 IpcChannel channel = new IpcChannel("CurrentIPC"); 

     ChannelServices.RegisterChannel(channel); 

     RemotingConfiguration.RegisterWellKnownServiceType(
      typeof(SimpleJob), "SimpleJob", WellKnownObjectMode.SingleCall); 
     RemotingConfiguration.RegisterWellKnownServiceType(
      typeof(ComplexObject), "ComplexObject", WellKnownObjectMode.SingleCall); 

我將不得不註冊了兩個作業類型。然後,調度工作,當我會把Windows服務端的類和名字,將代表客戶機(在web應用端執行的對象),我將只是IJob綁定類的傳遞的名稱是這樣的:

Dictionary<string, IJob> jobs = new Dictionary<string, IJob>(); 
    void AddJob(string name) 
    { 
     IJob obj = (IJob)Activator.GetObject(typeof(IJob), string.Format("ipc://CurrentIPC/{0}", name)); 
     jobs.Add(name, obj); 
    } 

所以,現在我不需要操心我的應用程序和其他的東西引用,調度會做的工作不知道什麼,只是IJob接口和web應用程序端執行的任務。

如果我錯了或它太複雜了,還有一些其他更簡單的方法來做到這一點,或者有一些我不知道的陷阱,你能幫我嗎? 謝謝。

P.S. 此外還有一個想法,有單獨的調度程序,它將通過執行指向Web應用程序中的指定服務的鏈接直接運行Web應用程序方法,例如「http:// localhost:3030/Request/12」,就這樣,但在我的網絡應用程序中,您應該被授權執行此類請求,並且我們還有問題需要解決,並且在數千個計劃任務的情況下,我們將在網絡服務器上額外加載這些請求。

回答

2

我認爲你是在正確的軌道上,我會創建使用Quartz.NET的調度程序並將其託管在Windows服務中,因爲pp池回收問題。

它會觸發使用特定的URL任務/在你的web應用服務:■每個任務/服務無論是在你的web應用程序或一個單獨的Web服務實例。

使用這種分離的調度程序只需要知道的網址和日程表,並不需要直接引用您的應用程序。這在未來的項目中也是可重用的。

+0

如果選擇了這種方法,可能會出現另一個問題。併發 - 調用相同的作業url將觸發兩個作業執行。如果是電子郵件,您可能會最終發送兩封相同的電子郵件。 –

+1

這是真的,如果這是一個問題,那麼可能需要一些安全措施,或者在調度程序中假定url唯一標識作業實例或可能在作業中,假設作業能夠識別類似作業正在運行或已經完成。 –

1

我知道,這不是託管Web應用程序的網絡服務器事業裏面調度可以回收應用程序池,等一個好主意,,所以我決定用它的Windows服務內...

爲什麼複雜?爲什麼不簡單並使用外部服務在一段時間內運行webhook?

我使用這個服務,我已經高興,儘管它是那麼容易,我可以在此基礎上簡單的程序創建自己的服務:

http://momentapp.com/

簡化呼叫:

private void Run() { 
    try { 
     var work = RequestNewMessage(); // get work 
     ProcessWork(work); // process work 
     // Log work 
    } 
    catch(Exception ex) { 
     // Log Error 
    } 
    finally { 
     // set job for now plus1 minute 
     SetRecuringJob(DateTime.UtcNow.AddMinute(1)); 
    } 
} 

private void SetRecuringJob(DateTime dt) { 
    PostJob("https://momentapp.com/jobs/new?job[at]={0:s}&job[method]=POST&job[uri]=http://yourapp.com/", dt); 
} 
0

如果你的問題是你不希望從WindowService引用整個web應用程序,我同意這一點,你爲什麼不乾脆創建一個實用程序DLL實現能夠通過打電話給你的web應用程序的通用工作一個普通的http url並將WCF REST服務實現爲「操作」? 這個我認爲將清理了一下架構,並保持絕緣的(和可重複使用)調度服務在您的組織。

0

我可能會丟失的要求,但你似乎能夠安裝的定製服務,這聽起來像你有過這臺機器的完全控制。所以你不妨爲你的定期任務安排一個Windows任務,這將爲你重複執行任務提供一個非常堅實的基礎。

可以安排一個VB腳本加載URL的及時,喜歡這裏:http://4rapiddev.com/internet/call-or-open-a-web-page-url-by-using-windows-task-scheduler-or-cronjob/

什麼都可以,當然,從批處理文件,在PowerShell來定製的可執行文件。

上升空間,以這種方式:

  • 你可以依靠默認的操作系統行爲什麼操作系統擅長:調度:)
  • 有已經爲管理員的UI(儘管不是一個Web UI)
  • 你有沒有依賴性,但OS

可能的缺點:

編輯:我似乎錯過了身份驗證的要求,但是當您使用Windows時,您可以允許在您的應用程序的某個區域進行Windows身份驗證。並且因爲您使用的計劃任務已通過Windows身份驗證,因此您已覆蓋此項目。我從來沒有在ASP.NET應用程序中大量使用過Windows身份驗證,但是您甚至可能只能使用自定義配置而無需額外的編程。

1

有點晚我想象,但仍然可以爲其他人有用。

這是一個我花了相當一段時間的項目,似乎滿足了大多數要求 - 事實上,我幾乎全部用於回調作業,如問題中所述。這也是我們內部使用的,所以我會盡量保持更新。

http://backgroundworker.codeplex.com/

這是非常類似石英,但對管理工作和他們的數據更集中。