定时任务 Wpf.Quartz.Demo.4
本文继续介绍定时任务 Wpf.Quartz.Demo.3的一些小细节, 代码也请前往第3节下载。
1.RichTextBox右键菜单
<RichTextBox.ContextMenu>
<ContextMenu>
<MenuItem Header="剪贴" Command="ApplicationCommands.Cut"/>
<MenuItem Header="复制" Command="ApplicationCommands.Copy"/>
<MenuItem Header="粘贴" Command="ApplicationCommands.Paste"/>
<MenuItem Header="清除" Click="MenuItemClear_Click"/>
<MenuItem x:Name="menuPause" Header="暂停" Click="MenuItemPause_Click"/>
</ContextMenu>
</RichTextBox.ContextMenu>
其中上面上个是系统默认的,自己要添加,可以自己定义。
2.右键DataGrid,选中该行。
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseRightButtonDown">
<local:ExInvokeCommandAction Command="{Binding PreviewMouseRightComamnd}" CommandParameter="{Binding SelectedItem, ElementName=table}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
private void PreviewMouseRight(object para)
{
RoutedEventArgs e = ((ExCommandParameter)para).EventArgs as RoutedEventArgs;
var treeViewItem = VisualUpwardSearch<UIElement>(e.OriginalSource as DependencyObject) as UIElement;
if (treeViewItem == null) return;
treeViewItem.Focus();
e.Handled = true;
}
private static DependencyObject VisualUpwardSearch<M>(DependencyObject source)
{
while (source != null && source.GetType() != typeof(M))
{
if (source is Visual || source is Visual3D)
source = VisualTreeHelper.GetParent(source);
else
source = LogicalTreeHelper.GetParent(source);
}
return source;
}
3.任务的基本接口,主要是系统的启动,停止等命令
public interface IRun:IBaseRunner
{
[Newtonsoft.Json.JsonIgnore()]
Action<string, LogLevel> LogOut { get; set; } Task Start(); Task Stop(); Task ReStart(); Task Resume(); Task Pause(); Task RunNowOneTime();
}
IRun
4.任务的设置的接口,主要是任务的配置保存。
public interface IBaseRunner
{
string Name { get; }
string DisplayName { get; set; }
string Remark { get; set; }
string CronExpression { get; set; }
TriggerState TriggerState { get; set; }
string SettingStr { get; set; }
DateTime? NextRunTime { get; }
DateTime[] NextRunTimes { get; set; }
DateTime? StartTime { get; set; }
DateTime? EndTime { get; set; }
bool IsEdit { get; set; }
CronSecondSet CronSecondSet { get; set; }
CronMinuteSet CronMinuteSet { get; set; }
CronHourSet CronHourSet { get; set; }
CronDaySet CronDaySet { get; set; }
CronMonthSet CronMonthSet { get; set; }
CronWeekSet CronWeekSet { get; set; }
CronYearSet CronYearSet { get; set; }
EasyCronSet EasyCronSet { get; set; }
Mode Mode { get; set; }
void Info(string message);
void DEBUG(string message);
void ERROR(string message);
void FATAL(string message);
void WARN(string message); }
IBaseRunner
5.任务类,接口IRun的实现。
using Quartz;
using Quartz.Impl;
using Quartz.Spi;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Wpf.Quartz.Converters; namespace Wpf.Quartz
{
public class SimpleRunner<T> : BaseRunner,IRun where T : IJob
{
public SimpleRunner()
{
base.Name = this.Name;
} private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public new string Name
{
//get { return GetType().Name; }
get { return typeof(T).Name; }
} private readonly SemaphoreSlim locker = new SemaphoreSlim(); public virtual async Task Start()
{
if (StatusEnableConverter.IsEanbleState(TriggerState, "Start") == false)
{
return;
}
await locker.WaitAsync();
try
{ if (string.IsNullOrEmpty(CronExpression))//如果为空,则设置为立刻执行一次
{
CronExpression = CronHelper.DateTime2Cron(DateTime.Now.AddSeconds());
}
Info((DisplayName ?? Name) + "开始启动!");
TriggerState= await QuartzHelper.Instance.StartJobExecuteByCron<T>(CronExpression, Name, this, this.StartTime, this.EndTime);
Info((DisplayName ?? Name) + "启动完毕!"); NextRunTimes = QuartzHelper.Instance.GetNextRunTime(CronExpression, StartTime, EndTime, );
IsEdit = false;
}
catch (Exception ex)
{
log.Fatal(ex);
Info((DisplayName ?? Name) + "启动失败!" + ex.Message);
}
finally
{
TriggerState = await QuartzHelper.Instance.GetJobState(Name);
locker.Release();
}
} public virtual async Task ReStart()
{
if (StatusEnableConverter.IsEanbleState(TriggerState, "ReStart") == false)
{
return;
}
await locker.WaitAsync();
try
{
if (string.IsNullOrEmpty(CronExpression))//如果为空,则设置为立刻执行一次
{
CronExpression = CronHelper.DateTime2Cron(DateTime.Now.AddSeconds());
}
Info(DisplayName??Name + "开始重新启动!");
TriggerState = await QuartzHelper.Instance.RemoveJob(Name);
TriggerState = await QuartzHelper.Instance.StartJobExecuteByCron<T>(CronExpression, Name, this, this.StartTime, this.EndTime);
Info((DisplayName ?? Name) + "重新启动完毕!"); NextRunTimes = QuartzHelper.Instance.GetNextRunTime(CronExpression, StartTime, EndTime, );
IsEdit = false;
}
catch (Exception ex)
{
log.Fatal(ex);
Info((DisplayName ?? Name) + "重新启动失败!" + ex.Message);
}
finally
{
TriggerState = await QuartzHelper.Instance.GetJobState(Name);
locker.Release();
}
} public virtual async Task Pause()
{
if (StatusEnableConverter.IsEanbleState(TriggerState, "Pause") == false)
{
return;
}
try
{
Info((DisplayName ?? Name) + "开始暂停!");
TriggerState = await QuartzHelper.Instance.PauseJob(Name);
Info((DisplayName ?? Name) + "暂停完毕!");
}
catch (Exception ex)
{
log.Fatal(ex);
Info((DisplayName ?? Name) + "暂停失败!" + ex.Message);
}
} public virtual async Task Resume()
{
if (StatusEnableConverter.IsEanbleState(TriggerState, "Resume") == false)
{
return;
}
try
{
Info((DisplayName ?? Name) + "开始恢复!");
TriggerState = await QuartzHelper.Instance.ResumeJob(Name);
Info((DisplayName ?? Name) + "恢复完毕!");
}
catch (Exception ex)
{
log.Fatal(ex);
Info((DisplayName ?? Name) + "恢复失败!" + ex.Message);
}
} public virtual async Task Stop()
{
if (StatusEnableConverter.IsEanbleState(TriggerState, "Stop") == false)
{
return;
}
try
{
Info((DisplayName ?? Name) + "开始停止!");
TriggerState = await QuartzHelper.Instance.RemoveJob(Name);
Info((DisplayName ?? Name) + "停止完毕!");
}
catch (Exception ex)
{
log.Fatal(ex);
Info((DisplayName ?? Name) + "停止失败!" + ex.Message);
}
} public virtual async Task RunNowOneTime()
{
if (StatusEnableConverter.IsEanbleState(TriggerState, "Run") == false)
{
return;
}
if (locker.CurrentCount == )
{
Info((DisplayName ?? Name) + "正在执行,请稍后再执行!");
return;
}
await locker.WaitAsync();
try
{
Info((DisplayName ?? Name) + "开始执行一次!");
ISchedulerFactory sf = new StdSchedulerFactory();
IScheduler scheduler = await sf.GetScheduler();
await scheduler.Start(); IJobDetail job = await scheduler.GetJobDetail(new JobKey(Name, "group1"));
if (job == null)
{
job = JobBuilder.Create<HelloJob>()
.WithIdentity(Name, "group1")
.Build();
} ITrigger trigger = await scheduler.GetTrigger(new TriggerKey(Name, "group1"));
if (trigger == null)
{
trigger = TriggerBuilder.Create()
.WithIdentity(Name, "group1")
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds())
.Build();
} await scheduler.ScheduleJob(job, trigger); Info((DisplayName ?? Name) + string.Format("执行一次完毕")); //await Task.Delay(TimeSpan.FromSeconds(5)); //await scheduler.Shutdown(); //SchedulerMetaData metaData = await scheduler.GetMetaData();
//Info(string.Format("执行完毕{0}个任务.", metaData.NumberOfJobsExecuted)); }
catch (Exception ex)
{
log.Fatal(ex);
Info((DisplayName ?? Name) + string.Format("执行一次失败") + ex.Message);
}
finally
{
locker.Release();
}
}
}
}
SimpleRunner
6.BaseRunner,主要是设置Cron
using Quartz;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Wpf.Quartz.Models; namespace Wpf.Quartz
{
public class BaseRunner: BaseLog, INotifyPropertyChanged
{
public string Name { get; set;} private string displayName;
public string DisplayName
{
get { return displayName; }
set
{
if (displayName != value)
{
displayName = value;
OnPropertyChanged("DisplayName");
}
}
} private string remark;
public string Remark
{
get { return remark; }
set
{
if (remark != value)
{
remark = value;
OnPropertyChanged("Remark");
}
}
} private string cronExpression;
public string CronExpression
{
get { return cronExpression; }
set
{
if (cronExpression != value)
{
cronExpression = value;
OnPropertyChanged("CronExpression");
}
}
} private TriggerState triggerState = TriggerState.None;
public TriggerState TriggerState
{
get { return triggerState; }
set
{
if (triggerState != value)
{
triggerState = value;
OnPropertyChanged("TriggerState");
}
}
} private string settingStr = "手动执行";
public string SettingStr
{
get { return settingStr; }
set
{
if (settingStr != value)
{
settingStr = value;
OnPropertyChanged("SettingStr");
}
}
} public DateTime? NextRunTime
{
get
{
if (NextRunTimes != null && NextRunTimes.Length > )
{
return NextRunTimes[];
}
else
{
return null;
}
} } private DateTime[] nextRunTimes;
public DateTime[] NextRunTimes
{
get { return nextRunTimes; }
set
{
if (nextRunTimes != value)
{
nextRunTimes = value;
OnPropertyChanged("NextRunTimes");
OnPropertyChanged("NextRunTime");
}
}
} private DateTime? startTime;
public DateTime? StartTime
{
get { return startTime; }
set
{
if (startTime != value)
{
startTime = value;
OnPropertyChanged("StartTime");
}
}
} private DateTime? endTime;
public DateTime? EndTime
{
get { return endTime; }
set
{
if (endTime != value)
{
endTime = value;
OnPropertyChanged("EndTime");
}
}
} private bool isEdit;
public bool IsEdit
{
get { return isEdit; }
set
{
if (isEdit != value)
{
isEdit = value;
OnPropertyChanged("IsEdit");
}
}
} public CronSecondSet CronSecondSet { get; set; } = new CronSecondSet();
public CronMinuteSet CronMinuteSet { get; set; } = new CronMinuteSet();
public CronHourSet CronHourSet { get; set; } = new CronHourSet();
public CronDaySet CronDaySet { get; set; } = new CronDaySet();
public CronMonthSet CronMonthSet { get; set; } = new CronMonthSet();
public CronWeekSet CronWeekSet { get; set; } = new CronWeekSet();
public CronYearSet CronYearSet { get; set; } = new CronYearSet();
public EasyCronSet EasyCronSet { get; set; } = new EasyCronSet(); private Mode mode;
public Mode Mode
{
get { return mode; }
set
{
if (mode != value)
{
mode = value;
OnPropertyChanged("Mode");
CronSecondSet.UpdateExpression();
}
}
} private SetMode setMode = SetMode.Easy;
public SetMode SetMode
{
get { return setMode; }
set
{
if (setMode != value)
{
setMode = value;
OnPropertyChanged("SetMode");
CronSecondSet.UpdateExpression();
}
}
} public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
} } public class BaseLog
{
#region 日志输出
[Newtonsoft.Json.JsonIgnore()]
public Action<string, LogLevel> LogOut { get; set; } public void Info(string message)
{
if (LogOut != null)
{
App.Current.Dispatcher.Invoke((Action)delegate ()
{
LogOut(message, LogLevel.INFO);
});
}
} public void DEBUG(string message)
{
if (LogOut != null)
{
App.Current.Dispatcher.Invoke((Action)delegate ()
{
LogOut(message, LogLevel.DEBUG);
});
}
} public void ERROR(string message)
{
if (LogOut != null)
{
App.Current.Dispatcher.Invoke((Action)delegate ()
{
LogOut(message, LogLevel.ERROR);
});
}
} public void FATAL(string message)
{
if (LogOut != null)
{
App.Current.Dispatcher.Invoke((Action)delegate ()
{
LogOut(message, LogLevel.FATAL);
});
}
} public void WARN(string message)
{
if (LogOut != null)
{
App.Current.Dispatcher.Invoke((Action)delegate ()
{
LogOut(message, LogLevel.WARN);
});
}
}
#endregion
}
}
BaseRunner
具体的请自行查看对应的类。
public CronSecondSet CronSecondSet { get; set; } = new CronSecondSet();
public CronMinuteSet CronMinuteSet { get; set; } = new CronMinuteSet();
public CronHourSet CronHourSet { get; set; } = new CronHourSet();
public CronDaySet CronDaySet { get; set; } = new CronDaySet();
public CronMonthSet CronMonthSet { get; set; } = new CronMonthSet();
public CronWeekSet CronWeekSet { get; set; } = new CronWeekSet();
public CronYearSet CronYearSet { get; set; } = new CronYearSet();
public EasyCronSet EasyCronSet { get; set; } = new EasyCronSet();
主要代码就是用户自定义设置,大家运行程序看效果。
另外,这种设置太专业了,不适合用户使用,因此设计了用户常用的模式。
是不是简单友好多了。
至此完结。
下次打算写一个wcf的Demo,当自己学习的动力。
定时任务 Wpf.Quartz.Demo.4的更多相关文章
- 定时任务 Wpf.Quartz.Demo.2
定时任务 Wpf.Quartz.Demo.1已经能运行了,本节开始用wpf搭界面. 准备工作: 1.界面选择MahApp.Metro 在App.xaml添加资源 <Application.Res ...
- 定时任务 Wpf.Quartz.Demo.1
Quartz 是个开源的作业调度框架. 安装:Install-Package Quartz 官网文档地址:https://www.quartz-scheduler.net/documentation/ ...
- 定时任务 Wpf.Quartz.Demo.5 (升级版)
老规矩:先把全部源码上传,见本文底部. 相对于Demo3的区别,就是能自动加载继承了IJob的任务,任务主体程序分离. 在exe执行文件的同级下建一个MyJobs的文件夹,每次会自动扫描该文件夹下的J ...
- 定时任务 Wpf.Quartz.Demo.3
先把全部源码上传,只是一个Demo,希望大家指点一下不足之处,见本文底部. 1.设置界面 2.详情页面 好了,现在慢慢叙述里面的一些方法. 3.实现拷贝的方法: (1) public static v ...
- [转][JAVA]定时任务之-Quartz使用篇
[BAT][JAVA]定时任务之-Quartz使用篇 定时任务之-Quartz使用篇 Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与 ...
- Spring整合quartz2.2.3总结,quartz动态定时任务,Quartz定时任务集群配置
Spring整合quartz2.2.3总结,quartz动态定时任务,Quartz定时任务集群配置 >>>>>>>>>>>>&g ...
- 震惊!Windows Service服务和定时任务框架quartz之间原来是这种关系……
过场CG: 接到公司领导的文件指示,“小熊”需要在6月底去海外执行一个行动代号为[定时任务]的营救计划,这个计划关系到公司某个项目的生死(数据安全漏洞),作战部拟定两个作战方案: 方案一:使用务定 ...
- SpringBoot定时任务 - 集成quartz实现定时任务(单实例和分布式两种方式)
最为常用定时任务框架是Quartz,并且Spring也集成了Quartz的框架,Quartz不仅支持单实例方式还支持分布式方式.本文主要介绍Quartz,基础的Quartz的集成案例本,以及实现基于数 ...
- Spring 整合 Quartz 实现动态定时任务(附demo)
最近项目中需要用到定时任务的功能,虽然Spring 也自带了一个轻量级的定时任务实现,但感觉不够灵活,功能也不够强大.在考虑之后,决定整合更为专业的Quartz来实现定时任务功能. 普通定时任务 首先 ...
随机推荐
- 第一个spring boot 程序
安装.运行.预览省略 错误1:8080端口被IIS占用,关闭它 Description: The Tomcat connector configured to listen on port 8080 ...
- js实现环形菜单效果
点击中间的圆点,会弹出环形菜单,效果图: 代码: <!DOCTYPE html> <html> <head> <meta charset="UTF- ...
- linux的!的用法
!的用法:1.!!:代表上一条命令,如下: 示例一: ./some-shell-command cat !! (相当于cat ./some-shell-command) 示例二: cd /user ! ...
- 【技术课堂】如何管理MongoDB数据库?
- springboot 增加过滤器方法
在访问服务器时,我们需要控制用户是否允许权限,这个时候可以使用过滤器. 在springboot 配置过滤器的方法如下: 编写过滤器代码: package com.neo.filter; import ...
- mysql (_mysql_exceptions.OperationalError) (1055, "Expression #1 of SELECT list is not in GROUP BY clause
sudo gedit /etc/mysql/my.cnf在打开的my.cnf文件中添加 sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES 保存,退 ...
- HDU 4310 Hero (贪心)
题意:给定你有 n 个敌人,你的伤害是 1,给出每个敌人的伤害,和敌人的血量,每一回合你可以攻击一个敌人,并且所有敌人都会攻击你,除非它已经死了,问你最少要多少要消耗多少血量. 析:一个很明显的贪心问 ...
- arguments[0]()的详解
var length = 10; function fn(){ console.log(this.length); } var obj = { length:5, method:function(fn ...
- Django继承AbstractUser新建User Model时出现fields.E304错误
错误内容如下 ERRORS: audit.UserProfile.groups: (fields.E304) Reverse accessor for 'UserProfile.groups' cla ...
- 如何悄悄地提升MySQL用户权限
温馨提示: 一次成功的非法提权,需要的必备条件是:1.对mysql权限表的查.改权限: 2.一次不经意的数据库服务器重启: 此次测试版本:5.6.25 准备邪恶用户: grant update on ...