如何在单独的AppDomain中运行Quartz.NET作业?

时间:2011-12-05 22:09:59

标签: quartz.net

是否可以在单独的AppDomain中运行Quartz.NET作业?如果是这样,怎么能实现呢?

1 个答案:

答案 0 :(得分: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的新实例。