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

(2)創(chuàng)建兩個類,一個是操作類,一個類繼承IJob 并且需要實現(xiàn)IJob的方法。?
/// <summary>
/// 操作類
/// </summary>
public class Operation : BaseBusiness<Auction>
{
#region 實例化
public Operation()
{
_options = new Options();
}
internal IOptions _options { get; }
#endregion
public static IScheduler scheduler;
public static ISchedulerFactory factory;
/// <summary>
/// 獲取cron表達式
/// </summary>
/// <param name="time">時間</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ù)對象主鍵</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);
}
//清楚所有定時任務(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;
//記錄兩個時間的差
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 + "時" + minutes + "分" + seconds + "秒";
//推送倒計時
PushHelper.AuctionCountDown(markId, days, hours, minutes, seconds);
//getTriggerState
});
}
/// <summary>
/// 設(shè)置定時任務(wù)
/// </summary>
/// <param name="Id">標的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);
}
}
以上是一個簡單的封裝,可以根據(jù)這個倒計時的推送。增加一些封裝 如:暫停,恢復(fù),結(jié)束,更新等。
調(diào)用的話只需要簡單的實例化一下進行調(diào)用。
然后我在大概說下其他封裝的思路和代碼片段;
延時倒計時:
根據(jù)傳過來的參數(shù)時間進行一個修改,刪除之前的任務(wù)重新開始一個任務(wù);
/// <summary>
/// 【拍賣延時】修改倒計時任務(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;
//拍賣進行中
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é)束時間 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é)束的定時任務(wù);
SetAuctioneds setAuctioneds = new SetAuctioneds();
setAuctioneds.SetEndQz(Id, FreeTime, Mid);
}
倒計時暫停:
調(diào)用組件的PauseTrigger方法可以進行暫停;
/// <summary>
/// 倒計時暫停
/// </summary>
public AjaxResult StopQz(string Id, string MId)
{
try
{
//方法1
//拍賣進行中
var GroupName = _options.GetPKById<Options_AuctionState>("1316283839361847296").ToString();
var mark = Service.GetIQueryable<MarkGoods>().FirstOrDefault(x => x.Id == MId);
if (mark == null)
return Error("找不到標的!");
//獲取實際結(jié)束時間。
var subEndTime = mark.EndTime.Value;
//計算暫停后剩余的時間 = audEndTime(結(jié)束時間) - 當前時間
var nowEndTime = DateTime.Now;
var DifferTime = subEndTime.Subtract(nowEndTime);
//追加 剩余時間 和 當前結(jié)束時間;
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;
////獲取實際結(jié)束時間。
//var subEndTime = mark.EndTime.Value;
////計算暫停后剩余的時間 = audEndTime(結(jié)束時間) - 當前時間
//var nowEndTime = DateTime.Now;
//var DifferTime = subEndTime.Subtract(nowEndTime);
////追加 剩余時間 和 當前結(jié)束時間;
//mark.SurplusTime = DifferTime.ToString();
////mark.EndTime = nowEndTime;
//Service.UpdateAny<MarkGoods>(mark, new List<string> { "SurplusTime" });
////拍賣進行中
//var GroupName = _options.GetPKById<Options_AuctionState>("1316283839361847296").ToString();
////關(guān)閉該定時器
//RemoveJob(mark.AuctionId, mark.Id, GroupName);
}
catch (Exception)
{
throw;
}
}
倒計時恢復(fù):
俗話說得好破鏡難圓,潑出去的水很難收回來?;謴?fù)也是這個道理,比如:倒計時走到了7暫停,那么恢復(fù)的時候如何從7繼續(xù)呢。這里就牽扯到了時間戳并且存入數(shù)據(jù)庫的介入了。
/// <summary>
/// 恢復(fù)倒計時
/// </summary>
public AjaxResult ReturnQz(string Id, string MId)
{
try
{
var mark = Service.GetIQueryable<MarkGoods>().FirstOrDefault(x => x.Id == MId);
if (mark == null)
return Error();
//獲取實際結(jié)束時間。
if (mark.SurplusTime.IsNullOrEmpty())
{
return Error();
}
TimeSpan.TryParse(mark.SurplusTime, out TimeSpan surplusTime);
//方法1
//拍賣進行中
//拍賣進行中
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ù)正在進行,無需恢復(fù)!");
}
else
{
//結(jié)束時間 = 當前時間 + 剩余時間
var endTime = DateTime.Now.Add(surplusTime);
//獲取限時競價時間
var LimitTime = endTime.AddHours(-mark.LimitHH.Value).AddMinutes(-mark.LimitMM.Value).AddSeconds(-mark.LimitSS.Value);
//修改倒計時任務(wù);
UpdateQz(mark.AuctionId, mark.Id, endTime, LimitTime);
//追加 剩余時間 和 當前結(jié)束時間;
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;
////獲取實際結(jié)束時間。
//if (mark.SurplusTime.IsNullOrEmpty())
//{
// return;
//}
//TimeSpan.TryParse(mark.SurplusTime, out TimeSpan surplusTime);
//TimeSpan a = new TimeSpan(1, 1, 1);
////結(jié)束時間 = 當前時間 + 剩余時間
//var endTime = DateTime.Now.Add(surplusTime);
////獲取限時競價時間
//var LimitTime = endTime.AddHours(-mark.LimitHH.Value).AddMinutes(-mark.LimitMM.Value).AddSeconds(-mark.LimitSS.Value);
////新增倒計時任務(wù);
//AddQz(mark.AuctionId, mark.Id, DateTime.Now, endTime, LimitTime);
////追加 剩余時間 和 當前結(jié)束時間;
//mark.SurplusTime = "";
//mark.EndTime = endTime;
//Service.UpdateAny<MarkGoods>(mark, new List<string> { "SurplusTime", "EndTime" });
}
catch (Exception ex)
{
throw;
}
}
以上代碼均是提供思路,使用時需要進行代碼簡單改動。?
以上就是C# Quartzs定時器的使用教程的詳細內(nèi)容,更多關(guān)于C# Quartzs定時器的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C# 函數(shù)覆蓋總結(jié)學(xué)習(xí)(推薦)
下面小編就為大家?guī)硪黄狢# 函數(shù)覆蓋總結(jié)學(xué)習(xí)(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-05-05
C#影院售票系統(tǒng)畢業(yè)設(shè)計(4)
這篇文章主要介紹了C#影院售票系統(tǒng)畢業(yè)設(shè)計,學(xué)習(xí)內(nèi)容是總結(jié)銷售信息的保存以及加載銷售信息,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2015-11-11
Unity3D UI Text得分數(shù)字增加的實例代碼
這篇文章主要介紹了Unity3D UI Text得分數(shù)字增加方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04
Silverlight將圖片轉(zhuǎn)換為byte的實現(xiàn)代碼
這篇文章主要介紹了Silverlight將圖片轉(zhuǎn)換為byte的實現(xiàn)代碼,需要的朋友可以參考下2015-11-11

