想实现类似插件一样的job,然后支持新增和删除。反射加载dll的话无法释放的,本地dll也无法删除。
删除任务时,顺便把任务所在的dll删除,如果不用appdomain的话,dll无法删除。
但使用appdomain的话,创建任务时无法识别是ijob类型,只有System.MarshalByRefObject 造成创建任务失败。
var type =Job.GetType();
IJobDetail jobDetail = JobBuilder.Create(type).WithIdentity(key).UsingJobData("ServerName", scheduler.SchedulerName)
.Build();//JobBuilder.Create(type) 使用appdomain后这一句报错。
[Serializable] public class ProxyObject1 : MarshalByRefObject { private Assembly assembly = null; public void LoadAssembly(string path) { assembly = Assembly.LoadFile(path); } public void AddJob(string jobName, string jobGoupName, string cron) { var obj = assembly.CreateInstance("TaskDll.TestDll"); var t = (Quartz.IJob)obj; JobInfo info = new JobInfo(); info.Job = t; info.JobGroupName = jobGoupName; info.JobName = jobName; info.StartTime = DateTime.Now; info.EndTime = DateTime.MaxValue; info.CronExpress = cron; QuartzHelper.Add(info); } }
AppDomainSetup setup = new AppDomainSetup(); setup.ShadowCopyFiles = "true"; var domain = AppDomain.CreateDomain(dllPath, null, setup); var loc = Assembly.GetExecutingAssembly().Location; var obj = (ProxyObject1)domain.CreateInstanceFromAndUnwrap(loc, "xx.ProxyObject1"); obj.LoadAssembly(dllPath); obj.AddJob(jobName, jobGroupName, Cron);
伪代码:
JobOptions : MarshalByRefObject {
static string jobname;
static string cron;
static void execute(); //job要执行的方法, 主程序保存对这个对象的引用, 然后达到触发条件后 invoke这个方法.
}
//主程序
var ad =appdomain.createdomain();
var ass = ad.load(your new job dll);
var (newjobname, newjobcron, newjobmethod)= ass.gettype("JobOptions").invoke(....)
var newjob= new jobwarpper(newjobname, newjobcron, newjobmethod);
JobBuilder.create(newjob... tirgger...);
问题已经解决哈,jobwarpper 类未找到,谢谢回答