コード例 #1
0
        /// <summary>
        /// 加载应用程序域
        /// </summary>
        /// <param name="assemblyName"></param>
        /// <returns></returns>
        public static PluginLoadContext LoadAssemblyContext(Guid sid, string assemblyName)
        {
            try
            {
                string            pluginLocation = GetTaskAssemblyPath(sid, assemblyName);
                PluginLoadContext loadContext    = new PluginLoadContext(pluginLocation);
                return(loadContext);

                //AppDomainSetup setup = new AppDomainSetup();
                //setup.ApplicationName = assemblyName;
                //setup.ApplicationBase = Path.GetDirectoryName(dllPath);
                //if (File.Exists(dllPath + ".config"))
                //{
                //    setup.ConfigurationFile = dllPath + ".config";
                //}
                ////setup.ShadowCopyFiles = "true"; //启用影像复制程序集
                ////setup.ShadowCopyDirectories = setup.ApplicationBase;
                ////AppDomain.CurrentDomain.SetShadowCopyFiles();
                //Assembly assembly = Assembly.Load(File.ReadAllBytes(dllPath));
                //AssemblyLoadContext context = new AssemblyLoadContext("");
                //AppDomain domain = AppDomain.CreateDomain(assemblyName, null, setup);
                ////AppDomain.MonitoringIsEnabled = true;
                //return domain;
            }
            catch (Exception exp)
            {
                LogHelper.Error($"加载应用程序域{assemblyName}失败!", exp);
                throw exp;
            }
        }
コード例 #2
0
        /// <summary>
        /// 加载应用程序域
        /// </summary>
        /// <param name="assemblyName"></param>
        /// <returns></returns>
        public static PluginLoadContext LoadAssemblyContext(Guid sid, string assemblyName)
        {
            string            pluginLocation = GetTaskAssemblyPath(sid, assemblyName);
            PluginLoadContext loadContext    = new PluginLoadContext(pluginLocation);

            return(loadContext);
        }
コード例 #3
0
        /// <summary>
        /// 卸载应用程序域
        /// </summary>
        /// <param name="context"></param>
        public static void UnLoadAssemblyLoadContext(PluginLoadContext context)
        {
            if (context != null)
            {
                context.Unload();

                GC.Collect();
                GC.WaitForPendingFinalizers();
            }
        }
コード例 #4
0
 /// <summary>
 /// 卸载应用程序域
 /// </summary>
 /// <param name="context"></param>
 public static void UnLoadAssemblyLoadContext(PluginLoadContext context)
 {
     if (context != null)
     {
         context.Unload();
         //for (int i = 0; context.weakReference.IsAlive && (i < 10); i++)
         {
             GC.Collect();
             GC.WaitForPendingFinalizers();
         }
     }
 }
コード例 #5
0
 public static TaskBase CreateTaskInstance(PluginLoadContext context, Guid sid, string assemblyName, string className)
 {
     try
     {
         string pluginLocation = GetTaskAssemblyPath(sid, assemblyName);
         var    assembly       = context.LoadFromAssemblyName(new AssemblyName(Path.GetFileNameWithoutExtension(pluginLocation)));
         Type   type           = assembly.GetType(className, true, true);
         return(Activator.CreateInstance(type) as TaskBase);
     }
     catch (Exception ex)
     {
         throw ex;
     }
 }
コード例 #6
0
        /// <summary>
        /// 启动一个任务,带重试机制
        /// </summary>
        /// <param name="task"></param>
        /// <returns></returns>
        public static async Task <bool> StartWithRetry(Guid sid)
        {
            var jk = new JobKey(sid.ToString().ToLower());

            if (await _scheduler.CheckExists(jk))
            {
                return(true);
            }
            ScheduleView view = await GetScheduleView(sid);

            PluginLoadContext lc = null;

            try
            {
                lc = AssemblyHelper.LoadAssemblyContext(view.Schedule.Id, view.Schedule.AssemblyName);
                for (int i = 0; i < 3; i++)
                {
                    try
                    {
                        await Start(view, lc);

                        return(true);
                    }
                    catch (SchedulerException sexp)
                    {
                        LogHelper.Error($"任务启动失败!开始第{i + 1}次重试...", sexp, view.Schedule.Id);
                    }
                }
                //最后一次尝试
                await Start(view, lc);

                return(true);
            }
            catch (SchedulerException sexp)
            {
                AssemblyHelper.UnLoadAssemblyLoadContext(lc);
                LogHelper.Error($"任务所有重试都失败了,已放弃启动!", sexp, view.Schedule.Id);
                return(false);
            }
            catch (Exception exp)
            {
                AssemblyHelper.UnLoadAssemblyLoadContext(lc);
                LogHelper.Error($"任务启动失败!", exp, view.Schedule.Id);
                return(false);
            }
        }
コード例 #7
0
        /// <summary>
        /// 启动一个任务,带重试机制
        /// </summary>
        /// <param name="task"></param>
        /// <param name="callBack"></param>
        /// <returns></returns>
        public static async Task <bool> StartWithRetry(ScheduleView view, Action <Guid, DateTime?> callBack)
        {
            PluginLoadContext lc = null;

            try
            {
                lc = AssemblyHelper.LoadAssemblyContext(view.Schedule.Id, view.Schedule.AssemblyName);
                for (int i = 0; i < 3; i++)
                {
                    try
                    {
                        await Start(view, lc, callBack);

                        return(true);
                    }
                    catch (SchedulerException sexp)
                    {
                        LogHelper.Error($"任务启动失败!开始第{i + 1}次重试...", sexp, view.Schedule.Id);
                    }
                }
                //最后一次尝试
                await Start(view, lc, callBack);

                return(true);
            }
            catch (SchedulerException sexp)
            {
                AssemblyHelper.UnLoadAssemblyLoadContext(lc);
                LogHelper.Error($"任务所有重试都失败了,已放弃启动!", sexp, view.Schedule.Id);
                return(false);
            }
            catch (Exception exp)
            {
                AssemblyHelper.UnLoadAssemblyLoadContext(lc);
                LogHelper.Error($"任务启动失败!", exp, view.Schedule.Id);
                return(false);
            }
        }
コード例 #8
0
        private static async Task Start(ScheduleView view, PluginLoadContext lc)
        {
            //throw

            //在应用程序域中创建实例返回并保存在job中,这是最终调用任务执行的实例
            TaskBase instance = AssemblyHelper.CreateTaskInstance(lc, view.Schedule.Id, view.Schedule.AssemblyName, view.Schedule.ClassName);

            if (instance == null)
            {
                throw new InvalidCastException($"任务实例创建失败,请确认目标任务是否派生自TaskBase类型。程序集:{view.Schedule.AssemblyName},类型:{view.Schedule.ClassName}");
            }
            // instance.logger = new LogWriter(); ;
            JobDataMap map = new JobDataMap
            {
                new KeyValuePair <string, object> ("domain", lc),
                new KeyValuePair <string, object> ("instance", instance),
                new KeyValuePair <string, object> ("name", view.Schedule.Title),
                new KeyValuePair <string, object> ("params", ConvertParamsJson(view.Schedule.CustomParamsJson)),
                new KeyValuePair <string, object> ("keepers", view.Keepers),
                new KeyValuePair <string, object> ("children", view.Children)
            };

            try
            {
                IJobDetail job = JobBuilder.Create <RootJob>()
                                 .WithIdentity(view.Schedule.Id.ToString())
                                 .UsingJobData(map)
                                 .Build();

                //添加触发器
                var listener = new JobRunListener(view.Schedule.Id.ToString());
                listener.OnSuccess += StartedEvent;
                _scheduler.ListenerManager.AddJobListener(listener, KeyMatcher <JobKey> .KeyEquals(new JobKey(view.Schedule.Id.ToString())));

                if (view.Schedule.RunLoop)
                {
                    if (!CronExpression.IsValidExpression(view.Schedule.CronExpression))
                    {
                        throw new Exception("cron表达式验证失败");
                    }
                    CronTriggerImpl trigger = new CronTriggerImpl
                    {
                        CronExpressionString = view.Schedule.CronExpression,
                        Name        = view.Schedule.Title,
                        Key         = new TriggerKey(view.Schedule.Id.ToString()),
                        Description = view.Schedule.Remark
                    };
                    if (view.Schedule.StartDate.HasValue)
                    {
                        trigger.StartTimeUtc = TimeZoneInfo.ConvertTimeToUtc(view.Schedule.StartDate.Value);
                    }
                    if (view.Schedule.EndDate.HasValue)
                    {
                        trigger.EndTimeUtc = TimeZoneInfo.ConvertTimeToUtc(view.Schedule.EndDate.Value);
                    }
                    await _scheduler.ScheduleJob(job, trigger);
                }
                else
                {
                    DateTimeOffset start = TimeZoneInfo.ConvertTimeToUtc(DateTime.Now);
                    if (view.Schedule.StartDate.HasValue)
                    {
                        start = TimeZoneInfo.ConvertTimeToUtc(view.Schedule.StartDate.Value);
                    }
                    DateTimeOffset end = start.AddMinutes(1);
                    if (view.Schedule.EndDate.HasValue)
                    {
                        end = TimeZoneInfo.ConvertTimeToUtc(view.Schedule.EndDate.Value);
                    }
                    ITrigger trigger = TriggerBuilder.Create()
                                       .WithIdentity(view.Schedule.Id.ToString())
                                       .StartAt(start)
                                       .WithSimpleSchedule(x => x
                                                           .WithRepeatCount(1).WithIntervalInMinutes(1))
                                       .EndAt(end)
                                       .Build();
                    await _scheduler.ScheduleJob(job, trigger);
                }
            }
            catch (Exception ex)
            {
                throw new SchedulerException(ex);
            }
            LogHelper.Info($"任务[{view.Schedule.Title}]启动成功!", view.Schedule.Id);

            _ = Task.Run(() =>
            {
                while (true)
                {
                    var log = instance.ReadLog();
                    if (log != null)
                    {
                        LogManager.Queue.Write(new SystemLogEntity
                        {
                            Category   = log.Category,
                            Message    = log.Message,
                            ScheduleId = log.ScheduleId,
                            Node       = log.Node,
                            StackTrace = log.StackTrace,
                            TraceId    = log.TraceId,
                            CreateTime = log.CreateTime
                        });
                    }
                    else
                    {
                        Thread.Sleep(3000);
                    }
                }
            });
        }