Skip to content

Commit 0d40e36

Browse files
committed
add crontab task executor #1
1 parent 2c0cb17 commit 0d40e36

14 files changed

+510
-5
lines changed

README.md

+46
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,52 @@ cron expression parser and executor for dotnet core.
88
99
If you have any problems, make sure to file an issue here on Github.
1010

11+
# Crontab task executor #
12+
13+
## CronAttribute ##
14+
This library support annotation method only. if you want create a crontab task, simply add the `CronAttribute` on some method.
15+
16+
We also provide some advanced features that you can get by adding some parameters to the method to get the information associated with the current task.
17+
18+
Here are some [samples](sample):
19+
```csharp
20+
public class TestScheduler
21+
{
22+
[Cron("18/1 * * * * ? *", CronStringFormat.WithSecondsAndYears)]
23+
public static void Task1()
24+
{
25+
Debug.WriteLine($"Task..............1111_{DateTime.Now}");
26+
}
27+
28+
[Cron("28/1 * * * * ? *", CronStringFormat.WithSecondsAndYears)]
29+
public static void Task2(DateTime time, CrontabTask task)
30+
{
31+
Debug.WriteLine($"Task..............2222_{time}_{task.Method.Name}");
32+
}
33+
34+
[Cron("28/1 * * * * ? *", CronStringFormat.WithSecondsAndYears)]
35+
public static void Task3(DateTime time, CrontabTask task)
36+
{
37+
Debug.WriteLine($"Task..............3333_{time}_{task.Method.Name}");
38+
}
39+
40+
[Cron("1-8 * * * * ? *", CronStringFormat.WithSecondsAndYears)]
41+
[Cron("48/1 * * * * ? *", CronStringFormat.WithSecondsAndYears)]
42+
public static void Task4(DateTime time, CrontabTask task, CrontabTaskExecutor taskExecutor)
43+
{
44+
Debug.WriteLine($"Task..............Cron_{time}_{task.Method.Name}_{taskExecutor.Tasks.Count}");
45+
}
46+
}
47+
```
48+
49+
## Constructor ##
50+
51+
The `CrontabTaskExecutor` class contains a constructor that with one parameter, the parameter is `Func<MethodInfo, object> typeInstanceCreator`. `typeInstanceCreator` used to create an object instance where the task method is definded. this will be very useful!
52+
53+
In console application, you can initialize an instance of an object with the `new` keyword or reflection. and in web application, you can use `DI`(`dependency injection`) directly.
54+
55+
For better use this library in your Web application, see the [Yisoft.AspnetCore.Crontab](https://github.com/yisoft-aspnet/crontab) project.
56+
1157
# Support for the following cron expressions #
1258

1359
```

crontab.sln

+18-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{C698C263-3
1919
EndProject
2020
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yisoft.Crontab.UnitTests", "test\Yisoft.Crontab.UnitTests\Yisoft.Crontab.UnitTests.csproj", "{3BEA7ED9-CB28-4428-99DE-FE31F7A4383F}"
2121
EndProject
22+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sample", "sample", "{E031B909-90C6-4C57-9090-DC23571A6E9B}"
23+
EndProject
24+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CrontabSample.ConsoleApp", "sample\CrontabSample.ConsoleApp\CrontabSample.ConsoleApp.csproj", "{276C9513-E53C-49B2-B6C5-FFD5DEEFB3FC}"
25+
EndProject
26+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CrontabSample.ClassLibrary", "sample\CrontabSample.ClassLibrary\CrontabSample.ClassLibrary.csproj", "{45D97113-6306-40B9-8E24-B576F87D9C41}"
27+
EndProject
2228
Global
2329
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2430
Debug|Any CPU = Debug|Any CPU
@@ -33,17 +39,27 @@ Global
3339
{3BEA7ED9-CB28-4428-99DE-FE31F7A4383F}.Debug|Any CPU.Build.0 = Debug|Any CPU
3440
{3BEA7ED9-CB28-4428-99DE-FE31F7A4383F}.Release|Any CPU.ActiveCfg = Release|Any CPU
3541
{3BEA7ED9-CB28-4428-99DE-FE31F7A4383F}.Release|Any CPU.Build.0 = Release|Any CPU
42+
{276C9513-E53C-49B2-B6C5-FFD5DEEFB3FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
43+
{276C9513-E53C-49B2-B6C5-FFD5DEEFB3FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
44+
{276C9513-E53C-49B2-B6C5-FFD5DEEFB3FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
45+
{276C9513-E53C-49B2-B6C5-FFD5DEEFB3FC}.Release|Any CPU.Build.0 = Release|Any CPU
46+
{45D97113-6306-40B9-8E24-B576F87D9C41}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
47+
{45D97113-6306-40B9-8E24-B576F87D9C41}.Debug|Any CPU.Build.0 = Debug|Any CPU
48+
{45D97113-6306-40B9-8E24-B576F87D9C41}.Release|Any CPU.ActiveCfg = Release|Any CPU
49+
{45D97113-6306-40B9-8E24-B576F87D9C41}.Release|Any CPU.Build.0 = Release|Any CPU
3650
EndGlobalSection
3751
GlobalSection(SolutionProperties) = preSolution
3852
HideSolutionNode = FALSE
3953
EndGlobalSection
4054
GlobalSection(NestedProjects) = preSolution
4155
{476A1529-5AF8-4D12-BBDF-396BDD2D0651} = {B7A6F3B1-5A1F-481F-AF8D-E27BF73D5A49}
4256
{3BEA7ED9-CB28-4428-99DE-FE31F7A4383F} = {C698C263-3412-4F65-8CF9-98CF9B31F0F1}
57+
{276C9513-E53C-49B2-B6C5-FFD5DEEFB3FC} = {E031B909-90C6-4C57-9090-DC23571A6E9B}
58+
{45D97113-6306-40B9-8E24-B576F87D9C41} = {E031B909-90C6-4C57-9090-DC23571A6E9B}
4359
EndGlobalSection
4460
GlobalSection(ExtensibilityGlobals) = postSolution
45-
RESX_SortFileContentOnSave = True
46-
RESX_ResXSortingComparison = InvariantCultureIgnoreCase
4761
RESX_AutoCreateNewLanguageFiles = True
62+
RESX_ResXSortingComparison = InvariantCultureIgnoreCase
63+
RESX_SortFileContentOnSave = True
4864
EndGlobalSection
4965
EndGlobal
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFrameworks>netstandard1.6;net46</TargetFrameworks>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<ProjectReference Include="..\..\src\Yisoft.Crontab\Yisoft.Crontab.csproj" />
9+
</ItemGroup>
10+
11+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// ) *
2+
// ( /( * ) ( ( `
3+
// )\()) ( ` ) /( ( )\ )\))(
4+
// ((_)\ )\ ( )(_)))\ ((((_)( ((_)()\
5+
// __ ((_)((_) (_(_())((_) )\ _ )\ (_()((_)
6+
// \ \ / / (_) |_ _|| __|(_)_\(_)| \/ |
7+
// \ V / | | _ | | | _| / _ \ | |\/| |
8+
// |_| |_|(_)|_| |___|/_/ \_\ |_| |_|
9+
//
10+
// This file is subject to the terms and conditions defined in
11+
// file 'License.txt', which is part of this source code package.
12+
//
13+
// Copyright © Yi.TEAM. All rights reserved.
14+
// -------------------------------------------------------------------------------
15+
16+
using System;
17+
using System.Diagnostics;
18+
using Yisoft.Crontab;
19+
20+
namespace CrontabSample.ClassLibrary.Schedulers
21+
{
22+
public class TestScheduler
23+
{
24+
[Cron("18/1 * * * * ? *", CronStringFormat.WithSecondsAndYears)]
25+
public static void Task1()
26+
{
27+
Debug.WriteLine($"Task..............1111_{DateTime.Now}");
28+
}
29+
30+
[Cron("28/1 * * * * ? *", CronStringFormat.WithSecondsAndYears)]
31+
public static void Task2(DateTime time, CrontabTask task)
32+
{
33+
Debug.WriteLine($"Task..............2222_{time}_{task.Method.Name}");
34+
}
35+
36+
[Cron("28/1 * * * * ? *", CronStringFormat.WithSecondsAndYears)]
37+
public static void Task3(DateTime time, CrontabTask task)
38+
{
39+
Debug.WriteLine($"Task..............3333_{time}_{task.Method.Name}");
40+
}
41+
42+
[Cron("1-8 * * * * ? *", CronStringFormat.WithSecondsAndYears)]
43+
[Cron("48/1 * * * * ? *", CronStringFormat.WithSecondsAndYears)]
44+
public static void Task4(DateTime time, CrontabTask task, CrontabTaskExecutor taskExecutor)
45+
{
46+
Debug.WriteLine($"Task..............Cron_{time}_{task.Method.Name}_{taskExecutor.Tasks.Count}");
47+
}
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFrameworks>netcoreapp1.1;net46</TargetFrameworks>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<ProjectReference Include="..\CrontabSample.ClassLibrary\CrontabSample.ClassLibrary.csproj" />
10+
</ItemGroup>
11+
12+
</Project>
+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// ) *
2+
// ( /( * ) ( ( `
3+
// )\()) ( ` ) /( ( )\ )\))(
4+
// ((_)\ )\ ( )(_)))\ ((((_)( ((_)()\
5+
// __ ((_)((_) (_(_())((_) )\ _ )\ (_()((_)
6+
// \ \ / / (_) |_ _|| __|(_)_\(_)| \/ |
7+
// \ V / | | _ | | | _| / _ \ | |\/| |
8+
// |_| |_|(_)|_| |___|/_/ \_\ |_| |_|
9+
//
10+
// This file is subject to the terms and conditions defined in
11+
// file 'License.txt', which is part of this source code package.
12+
//
13+
// Copyright © Yi.TEAM. All rights reserved.
14+
// -------------------------------------------------------------------------------
15+
16+
using System;
17+
using CrontabSample.ClassLibrary.Schedulers;
18+
using Yisoft.Crontab;
19+
20+
namespace CrontabSample.ConsoleApp
21+
{
22+
internal class Program
23+
{
24+
protected static void Main(string[] args)
25+
{
26+
var taskScanner = new CrontabTaskScaner();
27+
var tasks = taskScanner.ScanTasks();
28+
29+
if (tasks != null)
30+
{
31+
foreach (var task in tasks)
32+
{
33+
Console.WriteLine($"{task.ClassType}, {task.Method.Name}, {task.Cron.Expression}, {task.Cron.Format}");
34+
}
35+
36+
Console.WriteLine($"{tasks.Count}");
37+
}
38+
39+
Console.ReadKey();
40+
41+
var executor = new CrontabTaskExecutor(m =>
42+
{
43+
var classType = m.DeclaringType;
44+
45+
return classType == typeof(TestScheduler) ? new TestScheduler() : null;
46+
});
47+
48+
executor.AddTasks(tasks);
49+
50+
executor.Run();
51+
52+
while (true)
53+
{
54+
// exit when press 'Q'
55+
if (Console.ReadKey().Key == ConsoleKey.Q) break;
56+
57+
executor.Stop();
58+
59+
Console.ReadKey();
60+
61+
executor.Run();
62+
}
63+
}
64+
}
65+
}

src/Yisoft.Crontab/CronAttribute.cs

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// ) *
2+
// ( /( * ) ( ( `
3+
// )\()) ( ` ) /( ( )\ )\))(
4+
// ((_)\ )\ ( )(_)))\ ((((_)( ((_)()\
5+
// __ ((_)((_) (_(_())((_) )\ _ )\ (_()((_)
6+
// \ \ / / (_) |_ _|| __|(_)_\(_)| \/ |
7+
// \ V / | | _ | | | _| / _ \ | |\/| |
8+
// |_| |_|(_)|_| |___|/_/ \_\ |_| |_|
9+
//
10+
// This file is subject to the terms and conditions defined in
11+
// file 'License.txt', which is part of this source code package.
12+
//
13+
// Copyright © Yi.TEAM. All rights reserved.
14+
// -------------------------------------------------------------------------------
15+
16+
using System;
17+
18+
namespace Yisoft.Crontab
19+
{
20+
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
21+
public class CronAttribute : Attribute
22+
{
23+
public CronAttribute(string expression, CronStringFormat format = CronStringFormat.Default)
24+
{
25+
Expression = expression ?? throw new ArgumentNullException(nameof(expression));
26+
Format = format;
27+
}
28+
29+
public string Expression { get; }
30+
31+
public CronStringFormat Format { get; }
32+
}
33+
}

src/Yisoft.Crontab/CrontabTask.cs

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// ) *
2+
// ( /( * ) ( ( `
3+
// )\()) ( ` ) /( ( )\ )\))(
4+
// ((_)\ )\ ( )(_)))\ ((((_)( ((_)()\
5+
// __ ((_)((_) (_(_())((_) )\ _ )\ (_()((_)
6+
// \ \ / / (_) |_ _|| __|(_)_\(_)| \/ |
7+
// \ V / | | _ | | | _| / _ \ | |\/| |
8+
// |_| |_|(_)|_| |___|/_/ \_\ |_| |_|
9+
//
10+
// This file is subject to the terms and conditions defined in
11+
// file 'License.txt', which is part of this source code package.
12+
//
13+
// Copyright © Yi.TEAM. All rights reserved.
14+
// -------------------------------------------------------------------------------
15+
16+
using System;
17+
using System.Reflection;
18+
19+
namespace Yisoft.Crontab
20+
{
21+
public class CrontabTask
22+
{
23+
public CrontabTask(MethodInfo method, CronAttribute cron)
24+
{
25+
Method = method ?? throw new ArgumentNullException(nameof(method));
26+
Cron = cron ?? throw new ArgumentNullException(nameof(cron));
27+
28+
ClassType = Method.DeclaringType;
29+
Schedule = CrontabSchedule.TryParse(cron.Expression, cron.Format);
30+
Parameters = Method.GetParameters();
31+
}
32+
33+
public ParameterInfo[] Parameters { get; }
34+
35+
public Type ClassType { get; }
36+
37+
public MethodInfo Method { get; }
38+
39+
public CronAttribute Cron { get; }
40+
41+
public CrontabSchedule Schedule { get; }
42+
43+
internal Action<DateTime> Action { get; set; }
44+
45+
public CrontabTaskStatus Status { get; set; } = CrontabTaskStatus.Pending;
46+
47+
public DateTime LastExecuteTime { get; set; } = DateTime.MinValue;
48+
}
49+
}

0 commit comments

Comments
 (0)