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

本文关键字:net Quartz 情况下 远程作业 作业 程序集 副本 | 更新日期: 2023-09-27 18:00:27

我正试图在Quartz.net中创建一个用于调度的远程作业。当我在本地有一份包含该作业的程序集副本时,我可以执行类似于的操作

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

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

我想做的是,通过以存储在quartz_jobs.xml文件中的方式发送作业类型信息,可以在没有assebmly客户端副本的情况下创建时间表

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

如果没有本地副本,我一直无法弄清楚如何发送类类型信息。有人能解决这个问题吗?

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

这个问题真的困扰着我。我知道我可以动态生成类,所以我研究了如何生成。

步骤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服务接口,该接口将与服务驻留在同一服务器上,并呈现一个更加断开连接的接口。

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

  1. 使用特定且唯一的标识符在服务器端注册特定作业,而无需任何触发器(Quartz.NET允许您这样做)
  2. 在客户端,为具有特定标识符的作业创建触发器(不需要指定其类型-不需要引用客户端上的作业程序集),并在需要时创建参数列表
  3. 如果需要在作业实例中使用参数,请使用上下文。Trigger.JobData而不是上下文。工作详细信息

在这里你可以找到在我的项目中工作的源代码。