Quartz应用

背景:公司要上代发业务

需要突破点:

1.销售端根据不同的国家需要采用不同的销售策略
2.不同代发平台数据格式不一致,并且同一个产品同一个代发平台不同的国家sku不一样
3.同一个sku不同起运地库存数据不一致
.....

综合考虑,放弃api方式,以控制台+Quartz实现

private static string BuildModel = ConfigurationManager.AppSettings["BuildModel"];
private static string Countrys = ConfigurationManager.AppSettings["Countrys"];
static void Main(string[] args)
{
    if (string.IsNullOrEmpty(BuildModel)) { Console.WriteLine("检查BuildModel是否正确"); return; }
    if (BuildModel == "1")
    {
        #region 动态创建任务
        if (!string.IsNullOrEmpty(Countrys))
        {
            string[] countrys = Countrys.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var country in countrys)
            {
                if (country.ToLower() == "upload2wms") continue;
                string c1 = country.Split(new char[] { '_' })[0];
                string c2 = country.Split(new char[] { '_' })[1];
                File.Delete($@"{Path.GetFullPath("../..")}\VidaxlJob_{c1}_{c2}.cs");

                CodeCompileUnit unit = new CodeCompileUnit();
                CodeNamespace ns = new CodeNamespace("QuartzNet");
                ns.Imports.Add(new CodeNamespaceImport("Quartz"));

                CodeTypeDeclaration cls = new CodeTypeDeclaration($"VidaxlJob_{c1}_{c2}") { IsClass = true };
                cls.TypeAttributes = TypeAttributes.Public;
                ns.Types.Add(cls);
                unit.Namespaces.Add(ns);
                CodeMemberMethod method = new CodeMemberMethod();
                method.Name = "Execute";
                method.Attributes = MemberAttributes.Public | MemberAttributes.Final;
                method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(IJobExecutionContext), "context"));
                method.Statements.Add(new CodeSnippetStatement($"   StartExecute(\"QuartzNet_{c1}_{c2}\", \"VidaxlJob_{c1}_{c2}\",\"{c1}\",\"{c2}\"); "));
                cls.Members.Add(method);

                CodeTypeDeclaration dec1 = new CodeTypeDeclaration("VidaxlJob") { IsClass = true };
                CodeTypeDeclaration dec2 = new CodeTypeDeclaration("IJob") { IsInterface = true };
                cls.BaseTypes.Add(new CodeTypeReference(dec1.Name));
                cls.BaseTypes.Add(new CodeTypeReference(dec2.Name));
                cls.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(DisallowConcurrentExecutionAttribute))));

                CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
                CodeGeneratorOptions options = new CodeGeneratorOptions();
                options.BracingStyle = "C";
                options.BlankLinesBetweenMembers = true;
                string scFile = $@"{Path.GetFullPath("../..")}\VidaxlJob_{c1}_{c2}.cs";
                using (System.IO.StreamWriter sw = new System.IO.StreamWriter(scFile))
                {
                    provider.GenerateCodeFromCompileUnit(unit, sw, options);
                }
            }
        }
        Console.WriteLine("第一步:动态创建任务成功,请先包含文件然后前往app.config修改BuildModel运行模式为'2'执行第二步");
        Console.ReadKey();
        #endregion
    }
    else if (BuildModel == "2")
    {
        #region 动态注册任务

        if (!string.IsNullOrEmpty(Countrys))
        {
            CodeCompileUnit scUnit = new CodeCompileUnit();
            CodeNamespace scNs = new CodeNamespace("QuartzNet");
            scNs.Imports.Add(new CodeNamespaceImport("Quartz"));
            scNs.Imports.Add(new CodeNamespaceImport("Quartz.Impl"));
            scNs.Imports.Add(new CodeNamespaceImport("System.Configuration"));
            CodeTypeDeclaration schedulerCls = new CodeTypeDeclaration($"Scheduler") { IsClass = true };
            schedulerCls.TypeAttributes = TypeAttributes.Public;
            scNs.Types.Add(schedulerCls);
            scUnit.Namespaces.Add(scNs);
            CodeMemberMethod schedulerMethod = new CodeMemberMethod();
            schedulerMethod.Name = "Start";
            schedulerMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Static;
            schedulerMethod.Statements.Add(new CodeSnippetStatement($@" 
                IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
                scheduler.Start(); "));
            string[] countrys = Countrys.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var country in countrys)
            {
                string c1 = country.Split(new char[] { '_' })[0];
                string c2 = country.Split(new char[] { '_' })[1];
                schedulerMethod.Statements.Add(new CodeSnippetStatement($@"   
                IJobDetail job_{c1}_{c2} = JobBuilder.Create<VidaxlJob_{c1}_{c2}>().Build();
                ITrigger trigger_{c1}_{c2} = TriggerBuilder.Create()
                  .WithIdentity(""trigger_{c1}_{c2}"", ""group_{c1}_{c2}"")
                  .WithCronSchedule(ConfigurationManager.AppSettings[""Cron_{c1}_{c2}""])
                     .Build();
                scheduler.ScheduleJob(job_{c1}_{c2}, trigger_{c1}_{c2}); "));
            }
            schedulerCls.Members.Add(schedulerMethod);

            CodeDomProvider scProvider = CodeDomProvider.CreateProvider("CSharp");
            CodeGeneratorOptions scOptions = new CodeGeneratorOptions();
            scOptions.BracingStyle = "C";
            scOptions.BlankLinesBetweenMembers = true;
            string outputFile = $@"{Path.GetFullPath("../..")}\Scheduler.cs";
            using (System.IO.StreamWriter sw = new System.IO.StreamWriter(outputFile))
            {
                scProvider.GenerateCodeFromCompileUnit(scUnit, sw, scOptions);
            }
        }
        Console.WriteLine("第二步:动态注册任务成功,请先包含文件然后前往app.config修改BuildModel运行模式为'3'执行第三步");
        Console.ReadKey();
        #endregion
    }
    else if (BuildModel == "3")
    {
        Console.WriteLine("第三步:正式自动调度任务");
        Scheduler.Start();
        Console.ReadKey();
    }
}

VidaxlJob.cs统一处理不同的代发供应商数据

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace QuartzNet
{
    [DisallowConcurrentExecution]
    public class VidaxlJob
    {
        private static VidaxlManager VidaxlManager = new VidaxlManager();
        private static string JobTimeout = ConfigurationManager.AppSettings["JobTimeout"];
        public void StartExecute(string log, string jobName, string supplierId, string countryShort)
        {
            byte[] buffer = Guid.NewGuid().ToByteArray();
            string BatchId = BitConverter.ToInt64(buffer, 0).ToString();
            string str = $"{DateTime.Now},任务:{jobName},批次号:{BatchId},countryShort:{countryShort},开始执行";
            Console.WriteLine(str);
            ExceptionlessManager.WriteExceptionLog(log, str, null, "", "");
            string path = "";
            ReturnMsg msg = null;
            if (supplierId == "V4787")
            {
                TimeSpan ts = TimeSpan.FromMilliseconds(Convert.ToDouble(new DataTable().Compute(JobTimeout, "")));
                CancellationTokenSource source = new CancellationTokenSource();
                Task t = Task.Run(() => { msg = VidaxlManager.DownloadVidaxlInfo(countryShort, BatchId, ref path); }, source.Token);
                if (!t.Wait(ts))
                {
                    str = $"{DateTime.Now},任务:{jobName},批次号:{BatchId},线程超时,等待下次自动重试";
                    Console.WriteLine(str);
                    ExceptionlessManager.WriteExceptionLog(log, str, null, "", "");
                    Console.WriteLine();
                    source.Cancel();
                    return;
                }
                if (msg.Status == 200)
                {
                    msg = VidaxlManager.InitVidaxlInfo(path, countryShort, BatchId);
                }
            }
            else if (supplierId == "V4353")
            {
                msg = VidaxlManager.RequestGigaInfo(BatchId, countryShort);
            }
            else if (supplierId == "V5046")
            {
                msg = VidaxlManager.InitBigBuyProductInfo(countryShort, BatchId);
            }
            str = $"{DateTime.Now},任务:{jobName},批次号:{BatchId},countryShort:{countryShort},执行状态:{msg.Status},执行结果:{msg.Msg}";
            Console.WriteLine(str);
            ExceptionlessManager.WriteExceptionLog(log, str, null, "", "");
            Console.WriteLine();
        }
    }
}

posted @ 2023-03-31 15:07  o李一波o  阅读(8)  评论(0编辑  收藏  举报