2011-12-05 49 views
4

是否可以在單獨的AppDomain中運行Quartz.NET作業?如果是這樣,這怎麼能實現呢?如何在單獨的AppDomain中運行Quartz.NET作業?

+0

爲什麼你需要這樣做?你的使用場景是什麼?如果您將調度程序作爲主應用程序的獨立Windows服務運行,那麼這還不夠嗎? – yorah

+0

運行時代碼隔離是主要原因。我有一些我想運行的無關工作(除其他外);但有一個共同的管理區域。 Quartz工作只是大型企業集成系統的一部分。 –

回答

4

聲明:我沒有試過這個,這只是一個想法。而且這些代碼都沒有被編譯,甚至。

創建一個自定義作業工廠,爲您的真實工作創建包裝。通過創建新的應用程序域並在該應用程序域中運行原始作業,讓此包裝程序實現Execute方法。

詳細信息:創建一個新類型的工作,說IsolatedJob : IJob。這份工作需要作爲構造函數參數的作業,它應該封裝類型:

internal class IsolatedJob: IJob 
{ 
    private readonly Type _jobType; 

    public AutofacJob(Type jobType) 
    { 
     if (jobType == null) throw new ArgumentNullException("jobType"); 
     _jobType = jobType; 
    } 

    public void Execute(IJobExecutionContext context) 
    { 
     // Create the job in the new app domain 
     System.AppDomain domain = System.AppDomain.CreateDomain("Isolation"); 
     var job = (IJob)domain.CreateInstanceAndUnwrap("yourAssembly", _jobType.Name); 
     job.Execute(context); 
    } 
} 

您可能需要創建的IJobExecutionContext的實現,從MarshalByRefObject和代理繼承調用到原始context對象。考慮到IJobExecutionContext提供訪問的其他對象的數量,我會試圖實現許多成員NotImplementedException,因爲在作業執行期間不需要大多數成員。

接下來您需要自定義作業工廠。這一點更容易:

internal class IsolatedJobFactory : IJobFactory 
{ 
    public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) 
    { 
     return NewJob(bundle.JobDetail.JobType); 
    } 

    private IJob NewJob(Type jobType) 
    { 
     return new IsolatedJob(jobType); 
    } 
} 

最後,你需要指示Quartz使用這個工作的工廠,而不是開箱即用。使用IScheduler.JobFactory屬性設置器並提供IsolatedJobFactory的新實例。

+0

你是否真的需要孤立的工作課程,不能將應用程序的東西移到工廠嗎?或者會導致泄漏。 – Betty

+0

只是重新閱讀我的答案,我認爲如果你可以離開而不編組原始的IJobExecutionContext(這似乎令人懷疑),那麼你將不需要IsolatedJobFactory。否則,你將需要一個鉤子(即IsolatedJobFactory中的Execute方法)來允許你將IJobExecutionContext參數轉換爲可以編組到另一個AppDomain的東西。 –

相關問題