簡體   English   中英

如何在沒有作業程序集的本地副本的情況下在Quartz.net中安排遠程作業?

[英]How do a schedule a remote job in Quartz.net without a local copy of the job assembly?

我正在嘗試為Quartz.net中的日程安排創建一個遠程作業。 當我在本地擁有包含作業的程序集的副本時,我可以做這樣的事情

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

這要求我在服務器和我正在創建計划的計算機上都有一個包含類DummyJob的程序集的副本。

我想做的是能夠通過發送作業類型信息以及存儲在quartz_jobs.xml文件中的方式來創建沒有客戶端組件的計划。

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

我沒有能夠弄清楚如何在沒有本地副本的情況下發送類類型信息。 有沒有人有這個好的解決方案?

這個問題真讓我煩惱。 我知道我可以動態生成課程,所以我研究了如何。

第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. 如果需要在作業實例中使用參數,請使用context.Trigger.JobData而不是context.JobDetails。

在這里,您可以找到適用於我的項目的源代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM