如何在没有作业程序集的本地副本的情况下在Quartz.net中安排远程作业?

时间:2011-06-27 17:55:43

标签: c# quartz.net typeof

我正在尝试为Quartz.net中的日程安排创建一个远程作业。当我在本地拥有包含作业的程序集的副本时,我可以执行类似这样的操作

    JobDetail job = new JobDetail("remotelyAddedJob", "default", typeof(DummyJob.DummyJob));

这要求我在服务器和我正在创建日程表的计算机上都有一个包含类DummyJob的程序集的副本。

我想做的是通过发送作业类型信息以及存储在quartz_jobs.xml文件中的方式来创建没有客户端副本的日程表

  <job-type>Quartz.Job.NoOpJob, Quartz</job-type>

我没有弄清楚如何在没有本地副本的情况下发送类类型信息。有没有人有这个好的解决方案?

2 个答案:

答案 0 :(得分:3)

这个问题真让我烦恼。我知道我可以动态生成课程,所以我研究了如何。

第1步:创建此类

using System;
using Quartz;
using System.Reflection;
using System.Reflection.Emit;

namespace TestQuartzTaskCreator {
    public class FakeJob {
        public static Type Create(string assemblyName, string typeName){
            AssemblyName aName = new AssemblyName(assemblyName);
            AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(
                    aName,
                    AssemblyBuilderAccess.RunAndSave);

            ModuleBuilder mb = ab.DefineDynamicModule(aName.Name, aName.Name + ".dll");

            TypeBuilder tb = mb.DefineType(typeName, TypeAttributes.Public);

            tb.AddInterfaceImplementation(typeof(IJob));

            MethodBuilder meth = tb.DefineMethod(
                "Execute",
                MethodAttributes.Public | MethodAttributes.Virtual,
                typeof(void),
                new Type[] { typeof(JobExecutionContext) });

            meth.DefineParameter(1,
                ParameterAttributes.In,
                "context");

            ILGenerator methIL = meth.GetILGenerator();
            methIL.Emit(OpCodes.Ldarg_0);

            Type t = null;
            try {
                // Finish the type.
                t = tb.CreateType();
            }
            catch (Exception ex) {
                System.Console.WriteLine(ex.ToString());
            }

//            ab.Save(aName.Name + ".dll");

            return t;
        }
    }
}

第2步:从此更改

JobDetail job = new JobDetail("remotelyAddedJob", "default", typeof(TestType));

到这个

JobDetail job = new JobDetail("remotelyAddedJob", "default", FakeJob.Create("TestAss", "TestType"));

步骤3:像以前一样运行(但没有在客户端中引用您的作业程序集的副本)

- 编辑 - 虽然这样做了我原本想要的,但它并没有解决从客户端环境使用Quartz.Net时的所有问题。检索作业需要程序集可用。

我目前的做法是创建一个Web服务接口,该接口将与服务驻留在同一服务器上,并提供更加断开连接的接口。

答案 1 :(得分:1)

布拉德的解决方案可能有效或部分有效,但似乎有更好的选择(没有这种动态类创作功夫):

  1. 使用特定且唯一的标识符在服务器端注册特定作业,而无需任何触发器(Quartz.NET允许您这样做);
  2. 在客户端创建具有特定标识符的作业的触发器(您不需要指定其类型 - 不需要在客户端上引用作业程序集)和参数列表(如果需要),
  3. 如果需要在作业实例中使用参数,请使用context.Trigger.JobData而不是context.JobDetails。
  4. HERE您可以找到适合我项目的源代码。