定时任务 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来实现定时任务功能. 普通定时任务 首先 ...
随机推荐
- Permutation Sequence LT60
The set [1,2,3,...,n] contains a total of n! unique permutations. By listing and labeling all of the ...
- MySQL复制(Replication)
引自:http://www.cnblogs.com/hustcat/archive/2009/12/19/1627525.html 1.复制概述 1.1.复制解决的问题数据复制技术有以下一些特点:(1 ...
- mybatis 一次执行多条语句
现在的一些互联网应用 为了提高性能,现在一般比较少的使用外键.不是不用,只是在创建数据库不标明外键关系,用程序去维护. 为了维护数据一致性,我们需要手动完成相关数据的删除 比如用户和用户的关注 当用户 ...
- fastcgi vc6.0demo
#include <WinSock2.h> #include <stdio.h> #pragma comment(lib, "ws2_32.lib") ty ...
- Python module : simuPOP
conda config --add channels conda-forge conda install simupop simuPOP is a general-purpose individua ...
- Django框架之验证码生成示例
一.生成随机颜色的图片 1)前端代码展示 <!DOCTYPE html> <html lang="en"> <head> <meta ch ...
- node 报错:Uncaught Error: Cannot find module "!!../../../node_modules/extract-webpack-plugin/loader.js
问题出在缺少less和less-loader 因为以上模块使用了less解析. 解决方法在dependencies添加 "less": "^2.7.1", & ...
- kafka 支持发布订阅
概述 一般消息队列的是实现是支持两种模式的,即点对点,还有一种是topic发布订阅者模式,比如ACTIVEMQ.KAFKA也支持这两种模式,但是实现的原理不一样. KAFKA 的消息被读取后,并不是马 ...
- latex字体
强调 方式:声明:\em 或者 命令\emph,后者是latex2e的命令 区别:声明与命令的作用范围不同:\em改变当前字体直到被其他相应的声明取消(也可以是\em本身),或者当前的环境结束为止,当 ...
- Mybatis-Plus 实战完整学习笔记(十一)------条件构造器删除,修改,conditon
1.修改功能--其他过滤方式跟select一样 /** * 修改条件构造器 * @throws SQLException */ @Test public void selectUpdate() thr ...