ABP+AdminLTE+Bootstrap Table權(quán)限管理系統(tǒng)一期
Github:https://github.com/Jimmey-Jiang/ABP-ASP.NET-Boilerplate-Project-CMS
Quartz簡(jiǎn)介
Quartz.NET是一個(gè)開(kāi)源的作業(yè)調(diào)度框架,是 OpenSymphony
的 Quartz API
的.NET移植,它用C#寫(xiě)成,可用于winform
和asp.net
應(yīng)用中。它提供了巨大的靈活性而不犧牲簡(jiǎn)單性。你能夠用它來(lái)為執(zhí)行一個(gè)作業(yè)而創(chuàng)建簡(jiǎn)單的或復(fù)雜的調(diào)度。它有很多特征,如:數(shù)據(jù)庫(kù)支持,集群,插件,支持cron-like
表達(dá)式等等。非常適合在平時(shí)的工作中,定時(shí)輪詢數(shù)據(jù)庫(kù)同步,定時(shí)郵件通知,定時(shí)處理數(shù)據(jù)等.
參考
對(duì)Quartz.NET不熟悉的可以先看下
官方學(xué)習(xí)文檔:http://www.quartz-scheduler.net/documentation/index.html
使用實(shí)例介紹:http://www.quartz-scheduler.net/documentation/quartz-2.x/quick-start.html
官方的源代碼下載:http://sourceforge.net/projects/quartznet/files/quartznet/
特性
它一些很好的特性:
- 支持集群,作業(yè)分組,作業(yè)遠(yuǎn)程管理。
- 自定義精細(xì)的時(shí)間觸發(fā)器,使用簡(jiǎn)單,作業(yè)和觸發(fā)分離。
- 數(shù)據(jù)庫(kù)支持,可以寄宿
Windows
服務(wù),WebSite
,winform
等。
Quartz框架的一些基礎(chǔ)概念解釋?zhuān)?/p>
名稱(chēng) | 描述 |
---|---|
Scheduler | 作業(yè)調(diào)度器。 |
IJob | 作業(yè)接口,繼承并實(shí)現(xiàn)Execute, 編寫(xiě)執(zhí)行的具體作業(yè)邏輯。 |
JobBuilder | 根據(jù)設(shè)置,生成一個(gè)詳細(xì)作業(yè)信息(JobDetail)。 |
TriggerBuilder | 根據(jù)規(guī)則,生產(chǎn)對(duì)應(yīng)的Trig |
實(shí)戰(zhàn)
- Web.config配置
基礎(chǔ)概念我就懶得講了,你也懶得聽(tīng)了,直接上代碼吧。
首先配置一下Web.config
,其實(shí)這步可有可無(wú),可以直接跳過(guò),只是為了配置一些常量,獲取固定的時(shí)間,但是不是必要的。
<sectionGroup name="JobList">
<section name="Job" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
</sectionGroup>
<JobList>
<Job>
<!--這里是一個(gè)任務(wù)節(jié)點(diǎn)-->
<add key="Url" value="http://www.baidu.com" />
<!--需要訪問(wèn)的Url-->
<add key="Hour" value="10" />
<!--開(kāi)始時(shí)間小時(shí)-->
<!--開(kāi)始時(shí)間小時(shí),注意:這里的小時(shí)為0-23,如果是1點(diǎn)的話就是1,而不是01-->
<add key="Minute" value="30" />
<!--開(kāi)始時(shí)間分鐘-->
<!--開(kāi)始時(shí)間分鐘,注意:同上0-59-->
</Job>
</JobList>
-
創(chuàng)建service
創(chuàng)建ISystemSchedulerService
以及SystemSchedulerService
,代碼上面都有詳細(xì)的注釋?zhuān)揖筒恢貜?fù)了。
接口:
public interface ISystemSchedulerService: IApplicationService
{
void StartScheduler();
}
service: SystemSchedulerService
public class SystemSchedulerService : ISystemSchedulerService
{
private IScheduler _scheduler;
public ILogger _Logger { get; set; }
public SystemSchedulerService()
{
_Logger = NullLogger.Instance;
}
public void StopScheduler()
{
_scheduler.Shutdown();
}
public void StartScheduler()
{
try
{
//這里讀取配置文件中的任務(wù)開(kāi)始時(shí)間
int hour = int.Parse(((NameValueCollection)ConfigurationManager.GetSection("JobList/Job"))["Hour"]);
int minute = int.Parse(((NameValueCollection)ConfigurationManager.GetSection("JobList/Job"))["Minute"]);
ISchedulerFactory schedulerFactory = new StdSchedulerFactory();//內(nèi)存調(diào)度
_scheduler = schedulerFactory.GetScheduler();
//創(chuàng)建一個(gè)Job來(lái)執(zhí)行特定的任務(wù)
IJobDetail myLogJob = new JobDetailImpl("myLogJob", typeof(MyLogJob));
//創(chuàng)建并定義觸發(fā)器的規(guī)則(每天執(zhí)行一次時(shí)間為:時(shí):分)
ITrigger trigger =
TriggerBuilder.Create()
.WithDailyTimeIntervalSchedule(
a => a.WithIntervalInHours(24).OnEveryDay().StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(hour, minute))).Build();
_scheduler.Clear();
//將創(chuàng)建好的任務(wù)和觸發(fā)規(guī)則加入到Quartz中
_scheduler.ScheduleJob(myLogJob, trigger);
//開(kāi)始
_scheduler.Start();
}
catch (Exception ex)
{
_Logger.Info(ex.Message);
}
}
}
Quartz API
Quartz API的關(guān)鍵接口和類(lèi)是:
-
IScheduler
- 與調(diào)度程序交互的主要API。
-IJob
- 您希望由調(diào)度程序執(zhí)行的組件實(shí)現(xiàn)的接口。 -
IJobDetail
- 用于定義作業(yè)的實(shí)例。 -
ITrigger
- 定義執(zhí)行給定Job的時(shí)間表的組件。 -
JobBuilder
- 用于定義/構(gòu)建obDetail
實(shí)例,它定義了Jobs
的實(shí)例。 -
TriggerBuilder
- 用于定義/構(gòu)建觸發(fā)器實(shí)例。
一個(gè)調(diào)度程序的生命周期是由它為界的創(chuàng)作,通過(guò)SchedulerFactory
和其有關(guān)方法的調(diào)用。一旦創(chuàng)建了IScheduler
接口,就可以使用添加,刪除和列出作業(yè)和觸發(fā)器,并執(zhí)行其他與調(diào)度相關(guān)的操作(例如暫停觸發(fā)器)。但是,調(diào)度程序不會(huì)實(shí)際上對(duì)任何觸發(fā)器(執(zhí)行作業(yè))執(zhí)行操作,直到使用Start()
方法啟動(dòng)它。
構(gòu)建作業(yè)定義的代碼塊使用使用流暢接口的JobBuilder
創(chuàng)建產(chǎn)品IJobDetail
。同樣,構(gòu)建觸發(fā)器的代碼塊使用TriggerBuilder
流暢的接口和特定于觸發(fā)器類(lèi)型的擴(kuò)展方法。可能的時(shí)間延長(zhǎng)方法是:
- WithCalendarIntervalSchedule
- WithCronSchedule
- WithDailyTimeIntervalSchedule
-
WithSimpleSchedule
image.png
示例中的ITrigger
其實(shí)可以不讀取配置信息的。這就是我說(shuō)的不用配置Web.config
也可以。效果如下,每隔10秒執(zhí)行一次。
ITrigger trigger =
TriggerBuilder.Create()
.WithDailyTimeIntervalSchedule(
a => a.WithIntervalInSeconds(10)).Build();
工作和觸發(fā)器
代碼:
public class MyLogJob : JobBase, ITransientDependency
{
public ILogger _Logger { get; set; }
public MyLogJob()
{
_Logger = NullLogger.Instance;
}
public override void Execute(IJobExecutionContext context)
{
try
{
_Logger.Info("QuartzJob 任務(wù)開(kāi)始運(yùn)行");
for (int i = 0; i < 10; i++)
{
_Logger.InfoFormat("QuartzJob 正在運(yùn)行{0}", i);
}
_Logger.Info("QuartzJob任務(wù)運(yùn)行結(jié)束");
}
catch (Exception ex)
{
_Logger.Error("運(yùn)行異常:"+ex.Message, ex);
}
}
}
當(dāng)作業(yè)的觸發(fā)器觸發(fā),Execute(..)
方法由調(diào)度程序的工作線程之一調(diào)用。傳遞給此方法的JobExecutionContext
對(duì)象為作業(yè)實(shí)例提供有關(guān)其“運(yùn)行時(shí)”環(huán)境的信息 ( 調(diào)度程序執(zhí)行的邏輯),觸發(fā)執(zhí)行的觸發(fā)器的邏輯。
JobDetail
對(duì)象是在Job
添加到調(diào)度器時(shí)由Quartz.NET
客戶端創(chuàng)建的。它包含Job的各種屬性設(shè)置,以及一個(gè)JobDataMap
,它可以用來(lái)存儲(chǔ)作業(yè)類(lèi)的給定實(shí)例的狀態(tài)信息
觸發(fā)器對(duì)象用于觸發(fā)作業(yè)的執(zhí)行(或“觸發(fā)”)。當(dāng)你想安排一個(gè)工作,你實(shí)例化一個(gè)觸發(fā)器并“調(diào)整”它的屬性來(lái)提供你想要的調(diào)度。觸發(fā)器也可能有一個(gè)與它們相關(guān)的JobDataMap
- 這對(duì)于傳遞參數(shù)到一個(gè)特定于觸發(fā)器的觸發(fā)的Job
是很有用的。Quartz
提供了一些不同的觸發(fā)器類(lèi)型,但最常用的類(lèi)型是SimpleTrigger
(接口ISimpleTrigger
)和CronTrigger
(接口ICronTrigger
)。
如果您需要“一次性”執(zhí)行(在某個(gè)特定時(shí)間只執(zhí)行一項(xiàng)作業(yè)),或者您需要在給定時(shí)間開(kāi)始工作,并且重復(fù)執(zhí)行N次,SimpleTrigger
會(huì)很方便的T之間執(zhí)行。如果您希望基于類(lèi)似日歷的時(shí)間表(例如“每個(gè)星期五,中午”或“每個(gè)月的第10天的10:15”)觸發(fā),則CronTrigger
非常有用。
public class UserInfoController : ABPCMSControllerBase
{
private readonly ISystemSchedulerService _iSystemSchedulerService;
public UserInfoController(ISystemSchedulerService iSystemSchedulerService)
{
_iSystemSchedulerService = iSystemSchedulerService;
}
[HttpGet]
[DontWrapResult]
public async Task<ActionResult> GetUserInfo()
{
_iSystemSchedulerService.StartScheduler();
}
}
然后我們?cè)谇芭_(tái)控制器里面調(diào)用ISystemSchedulerService
的StartScheduler()
方法。然后運(yùn)行項(xiàng)目。
然后我們打開(kāi)日志Web\App_Data\Logs\Logs.txt
,看下效果:
每隔十秒鐘執(zhí)行一次。
Abp.Quartz
ABP有內(nèi)建的持久化后臺(tái)job隊(duì)列和后臺(tái)worker
系統(tǒng)。如果對(duì)于后臺(tái)workers你有更高級(jí)的計(jì)劃安排需求,Quartz
會(huì)是一個(gè)更好的選擇。對(duì)于持久化后臺(tái)job隊(duì)列,Hangfire
也是一個(gè)好的選擇。
ABP中Quartz應(yīng)用其實(shí)蠻簡(jiǎn)單的。
- 首先Abp.Quartz nuget包
- 然后加上引入到項(xiàng)目中。
[DependsOn(
typeof(AbpQuartzModule)
)]
public class ABPCMSWebModule : AbpModule
{
}
- 創(chuàng)建Jobs
這里我們就用上面例子中的job,當(dāng)然創(chuàng)建一個(gè)新job,你可以實(shí)現(xiàn)Quartz
的IJob
接口,或者繼承JobBase
類(lèi)(定義在Abp.Quartz包),這個(gè)類(lèi)包含一些幫助屬性和方法(例如日志和本地化)。
public class MyLogJob : JobBase, ITransientDependency
{
public override void Execute(IJobExecutionContext context)
{
Logger.Info("Executed MyLogJob :)");
}
}
4.創(chuàng)建調(diào)度作業(yè)
IQuartzScheduleJobManager
接口被用來(lái)創(chuàng)建調(diào)度作業(yè)。你可以在類(lèi)中注入該接口(或者你可以在你的模塊的PostInitialize
方法中解析和使用它)來(lái)調(diào)度作業(yè)。這里我們把之前創(chuàng)建的MyLogJob引用進(jìn)來(lái)。
效果如下:
public async Task<ActionResult> ScheduleJob()
{
await _jobManager.ScheduleAsync<MyLogJob>(
job =>
{
job.WithIdentity("MyLogJobIdentity", "MyGroup")
.WithDescription("A job to simply write logs.");
},
trigger =>
{
trigger.StartNow()
.WithSimpleSchedule(schedule =>
{
schedule.RepeatForever()
.WithIntervalInSeconds(5)
.Build();
});
});
_jobManager.Start();
return Content("OK, scheduled!");
}
效果一樣。
經(jīng)過(guò)上面四步,就完成Abp.Quartz運(yùn)用,是挺簡(jiǎn)單的。
模塊初始化PostInitialize方法中調(diào)度作業(yè)
public override void PostInitialize()
{
var helloDependency = IocManager.Resolve<IHelloDependency>();
}
擴(kuò)展
SimpleTrigger
說(shuō)一下SimpleTrigger
,WithCronSchedule()
這里有三種方式,一種就是上面說(shuō)到的Web.config
配置,一種是WithCronSchedule
設(shè)置時(shí)間參數(shù)。還有一種是WithCronSchedule("")
擁有強(qiáng)大的Cron
時(shí)間表達(dá)式。
SimpleTrigge
r應(yīng)滿足你的日程安排需求,如果你需要在某個(gè)特定時(shí)刻及時(shí)執(zhí)行一次作業(yè),或者在特定時(shí)間執(zhí)行一次,然后在特定時(shí)間間隔重復(fù)執(zhí)行。如果你想讓觸發(fā)器在2018年1月13日上午11點(diǎn)23分54秒執(zhí)行,然后再執(zhí)行5次,每10秒執(zhí)行一次。
通過(guò)這個(gè)描述,你可能不會(huì)覺(jué)得奇怪的是,SimpleTrigger
的屬性包括:開(kāi)始時(shí)間和結(jié)束時(shí)間,重復(fù)計(jì)數(shù)和重復(fù)間隔。所有這些屬性都與您所期望的完全相同,只有一些與結(jié)束時(shí)間屬性相關(guān)的特殊注釋。
SimpleTrigger
實(shí)例是使用TriggerBuilder
(用于觸發(fā)器的主屬性)和WithSimpleSchedule
擴(kuò)展方法(用于SimpleTrigger
特有的屬性)構(gòu)建的。
在特定的時(shí)刻建立一個(gè)觸發(fā)器,不要重復(fù):
// trigger builder creates simple trigger by default, actually an ITrigger is returned
ISimpleTrigger trigger = (ISimpleTrigger) TriggerBuilder.Create()
.WithIdentity("trigger1", "group1")
.StartAt(myStartTime) // some Date
.ForJob("job1", "group1") // identify job with name, group strings
.Build();
建立一個(gè)特定時(shí)刻的觸發(fā)器,然后每十秒鐘重復(fù)十次:
trigger = TriggerBuilder.Create()
.WithIdentity("trigger3", "group1")
.StartAt(myTimeToStartFiring) // if a start time is not given (if this line were omitted), "now" is implied
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(10)
.WithRepeatCount(10)) // note that 10 repeats will give a total of 11 firings
.ForJob(myJob) // identify job with handle to its JobDetail itself
.Build();
建立一個(gè)觸發(fā)器,將在未來(lái)五分鐘內(nèi)觸發(fā)一次:
trigger = (ISimpleTrigger) TriggerBuilder.Create()
.WithIdentity("trigger5", "group1")
.StartAt(DateBuilder.FutureDate(5, IntervalUnit.Minute)) // use DateBuilder to create a date in the future
.ForJob(myJobKey) // identify job with its JobKey
.Build();
建立一個(gè)觸發(fā)器,現(xiàn)在會(huì)觸發(fā),然后每隔五分鐘重復(fù)一次,直到22:00:
trigger = TriggerBuilder.Create()
.WithIdentity("trigger7", "group1")
.WithSimpleSchedule(x => x
.WithIntervalInMinutes(5)
.RepeatForever())
.EndAt(DateBuilder.DateOf(22, 0, 0))
.Build();
建立一個(gè)觸發(fā)器,將在下一個(gè)小時(shí)的頂部執(zhí)行,然后每2小時(shí)重復(fù)一次:
trigger = TriggerBuilder.Create()
.WithIdentity("trigger8") // because group is not specified, "trigger8" will be in the default group
.StartAt(DateBuilder.EvenHourDate(null)) // get the next even-hour (minutes and seconds zero ("00:00"))
.WithSimpleSchedule(x => x
.WithIntervalInHours(2)
.RepeatForever())
// note that in this example, 'forJob(..)' is not called
// - which is valid if the trigger is passed to the scheduler along with the job
.Build();
await scheduler.scheduleJob(trigger, job);
另外一些常用的停止作業(yè)的指令常量
- MisfireInstruction.IgnoreMisfirePolicy
- MisfirePolicy.SimpleTrigger.FireNow
- MisfirePolicy.SimpleTrigger.RescheduleNowWithExistingRepeatCount
- MisfirePolicy.SimpleTrigger.RescheduleNowWithRemainingRepeatCount
- MisfirePolicy.SimpleTrigger.RescheduleNextWithRemainingCount
- MisfirePolicy.SimpleTrigger.RescheduleNextWithExistingCount
在構(gòu)建SimpleTriggers時(shí),可以將簡(jiǎn)單的時(shí)間表(通過(guò)SimpleSchedulerBuilder)指定為停止作業(yè)指令:
trigger = TriggerBuilder.Create()
.WithIdentity("trigger7", "group1")
.WithSimpleSchedule(x => x
.WithIntervalInMinutes(5)
.RepeatForever()
.WithMisfireHandlingInstructionNextWithExistingCount())
.Build();
Cron時(shí)間表達(dá)式。
Cron-Expressions
用于配置CronTrigger
的實(shí)例。Cron-Expressions
是由七個(gè)子表達(dá)式組成的字符串,它們描述了計(jì)劃的各個(gè)細(xì)節(jié)。這些子表達(dá)式用空格分隔,表示:
- Seconds
- Minutes
- Hours
- Day-of-Month
- Month
- Day-of-Week
- Year (optional field)
示例Cron表達(dá)式
下面是一些表達(dá)式及其含義的例子 - 你可以在CronTrigger
的API文檔中找到更多的例子
CronTrigger示例1 - 創(chuàng)建一個(gè)觸發(fā)器的表達(dá)式,每5分鐘觸發(fā)一次
"0 0/5 * * * ?"
CronTrigger示例2 - 一個(gè)表達(dá)式,用于創(chuàng)建在分鐘后10秒(即上午10:00:10,上午10:05:10等)每5分鐘觸發(fā)一次的觸發(fā)器。
"10 0/5 * * * ?"
CronTrigger示例3 - 一個(gè)表達(dá)式,用于在每個(gè)星期三和星期五的10:30,11:30,12:30和13:30創(chuàng)建一個(gè)觸發(fā)器。
"0 30 10-13 ? * WED,FRI"
CronTrigger示例4 - 一個(gè)表達(dá)式,用于創(chuàng)建一個(gè)觸發(fā)器,在每個(gè)月的第5天和第20天的上午8點(diǎn)到上午10點(diǎn)之間每隔半小時(shí)觸發(fā)一次。請(qǐng)注意,觸發(fā)器不會(huì)在上午10點(diǎn),僅在8點(diǎn),8點(diǎn),9點(diǎn)和9點(diǎn)30分
"0 0/30 8-9 5,20 * ?"
請(qǐng)注意,一些調(diào)度要求過(guò)于復(fù)雜,無(wú)法用一個(gè)觸發(fā)器來(lái)表示 - 例如“上午9點(diǎn)至上午10點(diǎn)之間每5分鐘一次,下午1點(diǎn)至10點(diǎn)之間每20分鐘一次”。在這種情況下解決方案是簡(jiǎn)單地創(chuàng)建兩個(gè)觸發(fā)器,并注冊(cè)他們兩個(gè)運(yùn)行相同的工作。
CronTrigger
實(shí)例使用TriggerBuilder
(用于觸發(fā)器的主屬性)和WithCronSchedule
擴(kuò)展方法(用于CronTrigger
特定的屬性)構(gòu)建。
您也可以使用CronScheduleBuilder
的靜態(tài)方法來(lái)創(chuàng)建計(jì)劃。
建立一個(gè)觸發(fā)器,每隔上午8點(diǎn)到下午5點(diǎn),每隔一分鐘一次:
trigger = TriggerBuilder.Create()
.WithIdentity("trigger3", "group1")
.WithCronSchedule("0 0/2 8-17 * * ?")
.ForJob("myJob", "group1")
.Build();
建立一個(gè)觸發(fā)器,每天在上午10:42開(kāi)始:
// we use CronScheduleBuilder's static helper methods here
trigger = TriggerBuilder.Create()
.WithIdentity("trigger3", "group1")
.WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(10, 42))
.ForJob(myJobKey)
.Build();
要么 -
trigger = TriggerBuilder.Create()
.WithIdentity("trigger3", "group1")
.WithCronSchedule("0 42 10 * * ?")
.ForJob("myJob", "group1")
.Build();
建立一個(gè)觸發(fā)器,將在星期三上午10:42,在系統(tǒng)默認(rèn)的時(shí)區(qū)以外的其他時(shí)間觸發(fā):
trigger = TriggerBuilder.Create()
.WithIdentity("trigger3", "group1")
.WithSchedule(CronScheduleBuilder
.WeeklyOnDayAndHourAndMinute(DayOfWeek.Wednesday, 10, 42)
.InTimeZone(TimeZoneInfo.FindSystemTimeZoneById("Central America Standard Time")))
.ForJob(myJobKey)
.Build();
要么 -
trigger = TriggerBuilder.Create()
.WithIdentity("trigger3", "group1")
.WithCronSchedule("0 42 10 ? * WED", x => x
.InTimeZone(TimeZoneInfo.FindSystemTimeZoneById("Central America Standard Time")))
.ForJob(myJobKey)
.Build();
以下指令可用于通知Quartz
在CronTrigger
發(fā)生停止作業(yè)時(shí)應(yīng)該執(zhí)行的操作。(本教程的“更多關(guān)于觸發(fā)器”部分介紹了停止作業(yè)情況)。這些指令被定義為常量(并且API文檔具有對(duì)其行為的描述)。說(shuō)明包括:
- MisfireInstruction.IgnoreMisfirePolicy
- MisfireInstruction.CronTrigger.DoNothing
- MisfireInstruction.CronTrigger.FireOnceNow
所有觸發(fā)器都有MisfireInstrution.SmartPolicy
指令可供使用,并且此指令也是所有觸發(fā)器類(lèi)型的默認(rèn)值。CronTrigger
將“智能策略”指令解釋為MisfireInstruction.CronTrigger.FireOnceNow。CronTrigger.UpdateAfterMisfire()
方法的API文檔解釋了此行為的確切詳細(xì)信息。
在構(gòu)建CronTriggers時(shí),您可以將缺火指令指定為cron時(shí)間表的一部分(通過(guò)WithCronSchedule擴(kuò)展方法):
trigger = TriggerBuilder.Create()
.WithIdentity("trigger3", "group1")
.WithCronSchedule("0 0/2 8-17 * * ?", x => x
.WithMisfireHandlingInstructionFireAndProceed())
.ForJob("myJob", "group1")
.Build();
其他
我們可以看一下,源碼中對(duì)IQuartzScheduleJobManager
的ScheduleAsync
方法的封裝,其實(shí)就是Scheduler.ScheduleJob
處理了一下。
如果要使用模塊的PostInitialize
方法中解析和使用它來(lái)調(diào)度作業(yè),也是可以的。
using System.Reflection;
using Abp.Dependency;
using Abp.Modules;
using Abp.Quartz.Configuration;
using Abp.Threading.BackgroundWorkers;
using Quartz;
namespace Abp.Quartz
{
[DependsOn(typeof (AbpKernelModule))]
public class AbpQuartzModule : AbpModule
{
public override void PreInitialize()
{
IocManager.Register<IAbpQuartzConfiguration, AbpQuartzConfiguration>();
Configuration.Modules.AbpQuartz().Scheduler.JobFactory = new AbpQuartzJobFactory(IocManager);
}
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
}
public override void PostInitialize()
{
IocManager.RegisterIfNot<IJobListener, AbpQuartzJobListener>();
Configuration.Modules.AbpQuartz().Scheduler.ListenerManager.AddJobListener(IocManager.Resolve<IJobListener>());
if (Configuration.BackgroundJobs.IsJobExecutionEnabled)
{
IocManager.Resolve<IBackgroundWorkerManager>().Add(IocManager.Resolve<IQuartzScheduleJobManager>());
}
}
}
}
JobBase
封裝的一些方法,繼承自IJob
ABP+AdminLTE+Bootstrap Table權(quán)限管理系統(tǒng)一期
Github:https://github.com/Jimmey-Jiang/ABP-ASP.NET-Boilerplate-Project-CMS