-
-
Notifications
You must be signed in to change notification settings - Fork 22
/
SchedulerHostedService.cs
77 lines (64 loc) · 2.54 KB
/
SchedulerHostedService.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CronScheduler.AspNetCore.Cron;
namespace CronScheduler.AspNetCore
{
public class SchedulerHostedService : HostedServiceBase
{
public event EventHandler<UnobservedTaskExceptionEventArgs> UnobservedTaskException;
private readonly List<SchedulerTaskWrapper> _scheduledTasks = new List<SchedulerTaskWrapper>();
public SchedulerHostedService(IEnumerable<IScheduledJob> scheduledTasks)
{
var referenceTime = DateTime.UtcNow;
foreach (var scheduledTask in scheduledTasks)
{
_scheduledTasks.Add(new SchedulerTaskWrapper
{
Schedule = CrontabSchedule.Parse(scheduledTask.CronSchedule),
Task = scheduledTask,
NextRunTime = referenceTime
});
}
}
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
await ExecuteOnceAsync(cancellationToken);
await Task.Delay(TimeSpan.FromMinutes(1), cancellationToken);
}
}
private async Task ExecuteOnceAsync(CancellationToken cancellationToken)
{
var taskFactory = new TaskFactory(TaskScheduler.Current);
var referenceTime = DateTime.UtcNow;
var tasksThatShouldRun = _scheduledTasks.Where(t => t.ShouldRun(referenceTime)).ToList();
foreach (var taskThatShouldRun in tasksThatShouldRun)
{
taskThatShouldRun.Increment();
await taskFactory.StartNew(
async () =>
{
try
{
await taskThatShouldRun.Task.ExecuteAsync(cancellationToken);
}
catch (Exception ex)
{
var args = new UnobservedTaskExceptionEventArgs(
ex as AggregateException ?? new AggregateException(ex));
UnobservedTaskException?.Invoke(this, args);
if (!args.Observed)
{
throw;
}
}
},
cancellationToken);
}
}
}
}