C# Quartzs定時(shí)器的使用教程
前言
首先想到倒計(jì)時(shí),定時(shí)任務(wù)。大家想到的肯定就是定時(shí)器。那么定時(shí)器在web和winfrom程序中有著很大的作用。那在服務(wù)器端有沒有像定時(shí)器一樣的存在呢。
有了這些需求,我找到了第三方的組件 Quartz.Net 來實(shí)現(xiàn)(源碼位置)
實(shí)現(xiàn)步驟
(1)第一步,通過NuGet下載Quartz.Net組件并且引用到當(dāng)前工程中

(2)創(chuàng)建兩個(gè)類,一個(gè)是操作類,一個(gè)類繼承IJob 并且需要實(shí)現(xiàn)IJob的方法。?
/// <summary>
/// 操作類
/// </summary>
public class Operation : BaseBusiness<Auction>
{
#region 實(shí)例化
public Operation()
{
_options = new Options();
}
internal IOptions _options { get; }
#endregion
public static IScheduler scheduler;
public static ISchedulerFactory factory;
/// <summary>
/// 獲取cron表達(dá)式
/// </summary>
/// <param name="time">時(shí)間</param>
/// <returns></returns>
public string GetCron(DateTime? time)
{
var txt = Convert.ToDateTime(time).ToString("yyyy-MM-dd-HH-mm-ss");
var arr = txt.Split('-');
var result = string.Format("{0} {1} {2} {3} {4} ? {5}", arr[5], arr[4], arr[3], arr[2], arr[1], arr[0]);
return result;
}
/// <summary>
/// 刪除job
/// </summary>
/// <param name="Id">拍賣數(shù)據(jù)對(duì)象主鍵</param>
/// <param name="GroupName">job的組名</param>
public void RemoveJob(string Id, string MarkGoodsId, string GroupName)
{
//var jobKey = new JobKey(GroupName + Id + MId + "j", GroupName);
var job = new JobKey(GroupName + Id + MarkGoodsId + "j", GroupName);
scheduler.DeleteJob(job);
}
//清楚所有定時(shí)任務(wù)
public void ClearJob()
{
if (scheduler != null)
{
scheduler.Clear();
}
}
}
public class SetAuctionings : Operation, IJob
{
public async Task Execute(IJobExecutionContext context)
{
await Task.Run(() =>
{
DateTime freeTime = context.JobDetail.JobDataMap.GetDateTime("FreeTime");
var now = DateTime.Now;
//記錄兩個(gè)時(shí)間的差
var days = freeTime.Subtract(now).Days;
var hours = freeTime.Subtract(now).Hours;
var minutes = freeTime.Subtract(now).Minutes;
var seconds = freeTime.Subtract(now).Seconds;
var result = days + "天" + hours + "時(shí)" + minutes + "分" + seconds + "秒";
//推送倒計(jì)時(shí)
PushHelper.AuctionCountDown(markId, days, hours, minutes, seconds);
//getTriggerState
});
}
/// <summary>
/// 設(shè)置定時(shí)任務(wù)
/// </summary>
/// <param name="Id">標(biāo)的ID</param>
public void AddQz(DateTime BeginTime, DateTime FreeTime)
{
var GroupName = _options.GetPKById<Options_AuctionState>("1316283839361847296").ToString();
factory = new StdSchedulerFactory();
scheduler = factory.GetScheduler().Result;
var jobKey = new JobKey(GroupName + Id + MId + "j", GroupName);
var GjobDetail = scheduler.GetJobDetail(jobKey);
if (GjobDetail != null)
{
//刪除任務(wù)
scheduler.DeleteJob(jobKey);
}
//設(shè)置Job StatefulJob
var job = JobBuilder.Create<SetAuctionings>()
.WithIdentity(GroupName + Id + MId + "j", GroupName)
.Build();
job.JobDataMap.Put("FreeTime", FreeTime);
//【方法1】 設(shè)置每秒執(zhí)行
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity(GroupName + Id + MId + "t", GroupName)
.WithSimpleSchedule(x => x.WithIntervalInSeconds(1)
.RepeatForever())
.StartAt(new DateTimeOffset(BeginTime))
.EndAt(new DateTimeOffset(FreeTime))
.Build();
//【方法2】
//var ExecSs = "0/1 * * * * ?";
//ITrigger trigger = TriggerBuilder.Create()
// .WithIdentity(GroupName + Id + MeetingPlace + "t", GroupName)
// .WithCronSchedule(ExecSs)
// .StartAt(new DateTimeOffset(BeginTime))
// .EndAt(new DateTimeOffset(FreeTime))
// .Build();
scheduler.ScheduleJob(job, trigger);
}
}
以上是一個(gè)簡(jiǎn)單的封裝,可以根據(jù)這個(gè)倒計(jì)時(shí)的推送。增加一些封裝 如:暫停,恢復(fù),結(jié)束,更新等。
調(diào)用的話只需要簡(jiǎn)單的實(shí)例化一下進(jìn)行調(diào)用。
然后我在大概說下其他封裝的思路和代碼片段;
延時(shí)倒計(jì)時(shí):
根據(jù)傳過來的參數(shù)時(shí)間進(jìn)行一個(gè)修改,刪除之前的任務(wù)重新開始一個(gè)任務(wù);
/// <summary>
/// 【拍賣延時(shí)】修改倒計(jì)時(shí)任務(wù)
/// </summary>
/// <param name="Id"></param>
/// <param name="MeetingPlace"></param>
/// <param name="FreeTime"></param>
public void UpdateQz(String Id, string Mid, DateTime FreeTime, DateTime LimitTime)
{
//scheduler = factory.GetScheduler().Result;
//if (scheduler == null)
// return;
//拍賣進(jìn)行中
var GroupName = _options.GetPKById<Options_AuctionState>("1316283839361847296").ToString();
var jobKey = new JobKey(GroupName + Id + Mid + "j", GroupName);
var GjobDetail = scheduler.GetJobDetail(jobKey);
if (GjobDetail.Result == null)
return;
var triggerKey = new TriggerKey(GroupName + Id + Mid + "t", GroupName);
var triggerr = scheduler.GetTrigger(triggerKey);
var triggerBuilder = triggerr.Result.GetTriggerBuilder();
//修改結(jié)束時(shí)間 WithCronSchedule(ExecSs).
ITrigger newTrigger = triggerBuilder.EndAt(new DateTimeOffset(FreeTime)).Build();
var job = GjobDetail.Result;
job.JobDataMap.Put("AuctionId", Id);
job.JobDataMap.Put("MarkId", Mid);
job.JobDataMap.Put("FreeTime", FreeTime);
job.JobDataMap.Put("LimitTime", LimitTime);
//刪除任務(wù)
scheduler.DeleteJob(jobKey);
scheduler.ScheduleJob(job, newTrigger);
//修改最終結(jié)束的定時(shí)任務(wù);
SetAuctioneds setAuctioneds = new SetAuctioneds();
setAuctioneds.SetEndQz(Id, FreeTime, Mid);
}
倒計(jì)時(shí)暫停:
調(diào)用組件的PauseTrigger方法可以進(jìn)行暫停;
/// <summary>
/// 倒計(jì)時(shí)暫停
/// </summary>
public AjaxResult StopQz(string Id, string MId)
{
try
{
//方法1
//拍賣進(jìn)行中
var GroupName = _options.GetPKById<Options_AuctionState>("1316283839361847296").ToString();
var mark = Service.GetIQueryable<MarkGoods>().FirstOrDefault(x => x.Id == MId);
if (mark == null)
return Error("找不到標(biāo)的!");
//獲取實(shí)際結(jié)束時(shí)間。
var subEndTime = mark.EndTime.Value;
//計(jì)算暫停后剩余的時(shí)間 = audEndTime(結(jié)束時(shí)間) - 當(dāng)前時(shí)間
var nowEndTime = DateTime.Now;
var DifferTime = subEndTime.Subtract(nowEndTime);
//追加 剩余時(shí)間 和 當(dāng)前結(jié)束時(shí)間;
mark.SurplusTime = DifferTime.ToString();
//mark.EndTime = nowEndTime;
//GroupName + Id + MId + "t", GroupName
var TriKey = new TriggerKey(GroupName + Id + MId + "t", GroupName);
var Result = scheduler.GetTriggerState(TriKey).Result;
if (Result == TriggerState.None)
{
return Error("失?。翰淮嬖诖巳蝿?wù)!");
}
if (Result == TriggerState.Paused)//暫停
{
return Success("失?。涸撊蝿?wù)已暫停!");
}
else
{
scheduler.PauseTrigger(TriKey);
mark.AucTimeStatus = 2;
Service.UpdateAny<MarkGoods>(mark, new List<string> { "SurplusTime", "AucTimeStatus" });
return Success("成功:任務(wù)已暫停");
}
//方法2
//var mark = Service.GetIQueryable<MarkGoods>().FirstOrDefault(x => x.Id == MId);
//if (mark == null)
// return;
////獲取實(shí)際結(jié)束時(shí)間。
//var subEndTime = mark.EndTime.Value;
////計(jì)算暫停后剩余的時(shí)間 = audEndTime(結(jié)束時(shí)間) - 當(dāng)前時(shí)間
//var nowEndTime = DateTime.Now;
//var DifferTime = subEndTime.Subtract(nowEndTime);
////追加 剩余時(shí)間 和 當(dāng)前結(jié)束時(shí)間;
//mark.SurplusTime = DifferTime.ToString();
////mark.EndTime = nowEndTime;
//Service.UpdateAny<MarkGoods>(mark, new List<string> { "SurplusTime" });
////拍賣進(jìn)行中
//var GroupName = _options.GetPKById<Options_AuctionState>("1316283839361847296").ToString();
////關(guān)閉該定時(shí)器
//RemoveJob(mark.AuctionId, mark.Id, GroupName);
}
catch (Exception)
{
throw;
}
}
倒計(jì)時(shí)恢復(fù):
俗話說得好破鏡難圓,潑出去的水很難收回來?;謴?fù)也是這個(gè)道理,比如:倒計(jì)時(shí)走到了7暫停,那么恢復(fù)的時(shí)候如何從7繼續(xù)呢。這里就牽扯到了時(shí)間戳并且存入數(shù)據(jù)庫的介入了。
/// <summary>
/// 恢復(fù)倒計(jì)時(shí)
/// </summary>
public AjaxResult ReturnQz(string Id, string MId)
{
try
{
var mark = Service.GetIQueryable<MarkGoods>().FirstOrDefault(x => x.Id == MId);
if (mark == null)
return Error();
//獲取實(shí)際結(jié)束時(shí)間。
if (mark.SurplusTime.IsNullOrEmpty())
{
return Error();
}
TimeSpan.TryParse(mark.SurplusTime, out TimeSpan surplusTime);
//方法1
//拍賣進(jìn)行中
//拍賣進(jìn)行中
var GroupName = _options.GetPKById<Options_AuctionState>("1316283839361847296").ToString();
var TriKey = new TriggerKey(GroupName + Id + MId + "t", GroupName);
var Result = scheduler.GetTriggerState(TriKey).Result;
if (Result == TriggerState.None)
{
return Error("失?。翰淮嬖诖巳蝿?wù)!");
}
if (Result == TriggerState.Normal)//暫停
{
return Error("失?。喝蝿?wù)正在進(jìn)行,無需恢復(fù)!");
}
else
{
//結(jié)束時(shí)間 = 當(dāng)前時(shí)間 + 剩余時(shí)間
var endTime = DateTime.Now.Add(surplusTime);
//獲取限時(shí)競(jìng)價(jià)時(shí)間
var LimitTime = endTime.AddHours(-mark.LimitHH.Value).AddMinutes(-mark.LimitMM.Value).AddSeconds(-mark.LimitSS.Value);
//修改倒計(jì)時(shí)任務(wù);
UpdateQz(mark.AuctionId, mark.Id, endTime, LimitTime);
//追加 剩余時(shí)間 和 當(dāng)前結(jié)束時(shí)間;
mark.SurplusTime = "";
mark.EndTime = endTime;
var C1 = endTime.Subtract(DateTime.Now);
var C2 = endTime.Subtract(LimitTime);
if (C1 > C2)
mark.AucTimeStatus = 0;
else
mark.AucTimeStatus = 1;
Service.UpdateAny<MarkGoods>(mark, new List<string> { "SurplusTime", "EndTime", "AucTimeStatus" });
return Success();
}
//方法2
//var mark = Service.GetIQueryable<MarkGoods>().FirstOrDefault(x => x.Id == MId);
//if (mark == null)
// return;
////獲取實(shí)際結(jié)束時(shí)間。
//if (mark.SurplusTime.IsNullOrEmpty())
//{
// return;
//}
//TimeSpan.TryParse(mark.SurplusTime, out TimeSpan surplusTime);
//TimeSpan a = new TimeSpan(1, 1, 1);
////結(jié)束時(shí)間 = 當(dāng)前時(shí)間 + 剩余時(shí)間
//var endTime = DateTime.Now.Add(surplusTime);
////獲取限時(shí)競(jìng)價(jià)時(shí)間
//var LimitTime = endTime.AddHours(-mark.LimitHH.Value).AddMinutes(-mark.LimitMM.Value).AddSeconds(-mark.LimitSS.Value);
////新增倒計(jì)時(shí)任務(wù);
//AddQz(mark.AuctionId, mark.Id, DateTime.Now, endTime, LimitTime);
////追加 剩余時(shí)間 和 當(dāng)前結(jié)束時(shí)間;
//mark.SurplusTime = "";
//mark.EndTime = endTime;
//Service.UpdateAny<MarkGoods>(mark, new List<string> { "SurplusTime", "EndTime" });
}
catch (Exception ex)
{
throw;
}
}
以上代碼均是提供思路,使用時(shí)需要進(jìn)行代碼簡(jiǎn)單改動(dòng)。?
以上就是C# Quartzs定時(shí)器的使用教程的詳細(xì)內(nèi)容,更多關(guān)于C# Quartzs定時(shí)器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C# 函數(shù)覆蓋總結(jié)學(xué)習(xí)(推薦)
下面小編就為大家?guī)硪黄狢# 函數(shù)覆蓋總結(jié)學(xué)習(xí)(推薦)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-05-05
C#影院售票系統(tǒng)畢業(yè)設(shè)計(jì)(4)
這篇文章主要介紹了C#影院售票系統(tǒng)畢業(yè)設(shè)計(jì),學(xué)習(xí)內(nèi)容是總結(jié)銷售信息的保存以及加載銷售信息,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2015-11-11
Unity3D UI Text得分?jǐn)?shù)字增加的實(shí)例代碼
這篇文章主要介紹了Unity3D UI Text得分?jǐn)?shù)字增加方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-04-04
Silverlight將圖片轉(zhuǎn)換為byte的實(shí)現(xiàn)代碼
這篇文章主要介紹了Silverlight將圖片轉(zhuǎn)換為byte的實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-11-11
Unity3D基于陀螺儀實(shí)現(xiàn)VR相機(jī)功能
這篇文章主要為大家詳細(xì)介紹了Unity3D基于陀螺儀實(shí)現(xiàn)VR相機(jī)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04

