Skip to content

Commit cf1d621

Browse files
committed
v3.1.0:
* Events added to ITask: BeforeRun, AfterRunSuccess * Tests optimized, now takes only 12 seconds
1 parent 4482bb3 commit cf1d621

File tree

6 files changed

+142
-65
lines changed

6 files changed

+142
-65
lines changed

src/RecurrentTasks/ExceptionEventArgs.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
{
33
using System;
44

5-
public class ExceptionEventArgs : EventArgs
5+
public class ExceptionEventArgs : ServiceProviderEventArgs
66
{
7-
public ExceptionEventArgs(Exception exception)
7+
public ExceptionEventArgs(IServiceProvider serviceProvider, Exception exception)
8+
:base(serviceProvider)
89
{
910
if (exception == null)
1011
{

src/RecurrentTasks/ITask.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,17 @@ public interface ITask
3838
TimeSpan Interval { get; set; }
3939

4040
/// <summary>
41-
/// Raises when exception catched during task run.
41+
/// Called before Run() is called (even before IsRunningRightNow set to true).
42+
/// </summary>
43+
event EventHandler<ServiceProviderEventArgs> BeforeRun;
44+
45+
/// <summary>
46+
/// Called after Run() sucessfully finished (after IsRunningRightNow set to false)
47+
/// </summary>
48+
event EventHandler<ServiceProviderEventArgs> AfterRunSuccess;
49+
50+
/// <summary>
51+
/// Called after Run() failed (after IsRunningRightNow set to false)
4252
/// </summary>
4353
event EventHandler<ExceptionEventArgs> AfterRunFail;
4454

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace RecurrentTasks
2+
{
3+
using System;
4+
5+
public class ServiceProviderEventArgs : EventArgs
6+
{
7+
public ServiceProviderEventArgs(IServiceProvider serviceProvider)
8+
{
9+
if (serviceProvider == null)
10+
{
11+
throw new ArgumentNullException(nameof(serviceProvider));
12+
}
13+
this.ServiceProvider = serviceProvider;
14+
}
15+
16+
public IServiceProvider ServiceProvider { get; protected set; }
17+
}
18+
}

src/RecurrentTasks/TaskRunner.cs

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,21 @@ public TaskRunner(ILoggerFactory loggerFactory, IServiceScopeFactory serviceScop
2828
RunStatus = new TaskRunStatus();
2929
}
3030

31+
/// <inheritdoc />
32+
public event EventHandler<ServiceProviderEventArgs> BeforeRun;
33+
34+
/// <inheritdoc />
3135
public event EventHandler<ExceptionEventArgs> AfterRunFail;
3236

37+
/// <inheritdoc />
38+
public event EventHandler<ServiceProviderEventArgs> AfterRunSuccess;
39+
3340
TaskRunStatus ITask.RunStatus { get { return RunStatus; } }
3441

42+
/// <inheritdoc />
3543
public TaskRunStatus RunStatus { get; protected set; }
3644

45+
/// <inheritdoc />
3746
public bool IsStarted
3847
{
3948
get
@@ -42,14 +51,18 @@ public bool IsStarted
4251
}
4352
}
4453

54+
/// <inheritdoc />
4555
public bool IsRunningRightNow { get; private set; }
4656

57+
/// <inheritdoc />
4758
public CultureInfo RunningCulture { get; set; }
4859

60+
/// <inheritdoc />
4961
public TimeSpan Interval { get; set; }
5062

5163
private IServiceScopeFactory ServiceScopeFactory { get; set; }
5264

65+
/// <inheritdoc />
5366
public void Start(TimeSpan firstRunDelay)
5467
{
5568
if (firstRunDelay < TimeSpan.Zero)
@@ -69,6 +82,7 @@ public void Start(TimeSpan firstRunDelay)
6982
mainTask = Task.Run(() => MainLoop(firstRunDelay));
7083
}
7184

85+
/// <inheritdoc />
7286
public void Stop()
7387
{
7488
logger.LogInformation("Stop() called...");
@@ -79,6 +93,7 @@ public void Stop()
7993
breakEvent.Set();
8094
}
8195

96+
/// <inheritdoc />
8297
public void TryRunImmediately()
8398
{
8499
if (mainTask == null)
@@ -122,7 +137,7 @@ protected void MainLoop(TimeSpan firstRunDelay)
122137

123138
try
124139
{
125-
OnBeforeRun();
140+
OnBeforeRun(scope.ServiceProvider);
126141

127142
IsRunningRightNow = true;
128143

@@ -142,7 +157,7 @@ protected void MainLoop(TimeSpan firstRunDelay)
142157
RunStatus.LastException = null;
143158
IsRunningRightNow = false;
144159

145-
OnAfterRunSuccess();
160+
OnAfterRunSuccess(scope.ServiceProvider);
146161
}
147162
catch (Exception ex)
148163
{
@@ -156,16 +171,7 @@ protected void MainLoop(TimeSpan firstRunDelay)
156171
RunStatus.FailsCount++;
157172
IsRunningRightNow = false;
158173

159-
OnAfterRunFail();
160-
161-
try
162-
{
163-
AfterRunFail?.Invoke(this, new ExceptionEventArgs(ex));
164-
}
165-
catch (Exception ex2)
166-
{
167-
logger.LogError(0, ex2, "Error while processing AfterRunFail event (ignored)");
168-
}
174+
OnAfterRunFail(scope.ServiceProvider, ex);
169175
}
170176
finally
171177
{
@@ -185,28 +191,48 @@ protected void MainLoop(TimeSpan firstRunDelay)
185191
logger.LogInformation("MainLoop() finished.");
186192
}
187193

188-
/// <summary>
189-
/// Called before Run() is called (even before IsRunningRightNow set to true)
190-
/// </summary>
191-
protected virtual void OnBeforeRun()
194+
/// <remarks>
195+
/// Invokes <see cref="BeforeRun"/> event - don't forget to call base.OnBeforeRun in override
196+
/// </remarks>
197+
protected virtual void OnBeforeRun(IServiceProvider serviceProvider)
192198
{
193-
// nothing
199+
BeforeRun?.Invoke(this, new ServiceProviderEventArgs(serviceProvider));
194200
}
195201

196-
/// <summary>
197-
/// Called after Run() sucessfully finished (after IsRunningRightNow set to false)
198-
/// </summary>
199-
protected virtual void OnAfterRunSuccess()
202+
/// <remarks>
203+
/// Invokes <see cref="AfterRunSuccess"/> event - don't forget to call base.OnAfterRunSuccess in override
204+
/// </remarks>
205+
/// <remarks>
206+
/// Attention! Any exception, catched during AfterRunSuccess.Invoke, is written to error log and ignored.
207+
/// </remarks>
208+
protected virtual void OnAfterRunSuccess(IServiceProvider serviceProvider)
200209
{
201-
// nothing
210+
try
211+
{
212+
AfterRunSuccess?.Invoke(this, new ServiceProviderEventArgs(serviceProvider));
213+
}
214+
catch (Exception ex2)
215+
{
216+
logger.LogError(0, ex2, "Error while processing AfterRunSuccess event (ignored)");
217+
}
202218
}
203219

204-
/// <summary>
205-
/// Called after Run() falied (after IsRunningRightNow set to false)
206-
/// </summary>
207-
protected virtual void OnAfterRunFail()
220+
/// <remarks>
221+
/// Invokes <see cref="AfterRunFail"/> event - don't forget to call base.OnAfterRunSuccess in override
222+
/// </remarks>
223+
/// <remarks>
224+
/// Attention! Any exception, catched during AfterRunFail.Invoke, is written to error log and ignored.
225+
/// </remarks>
226+
protected virtual void OnAfterRunFail(IServiceProvider serviceProvider, Exception ex)
208227
{
209-
// nothing
228+
try
229+
{
230+
AfterRunFail?.Invoke(this, new ExceptionEventArgs(serviceProvider, ex));
231+
}
232+
catch (Exception ex2)
233+
{
234+
logger.LogError(0, ex2, "Error while processing AfterRunFail event (ignored)");
235+
}
210236
}
211237
}
212238
}

src/RecurrentTasks/project.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
2-
"version": "3.0.0",
2+
"version": "3.1.0",
33
"title": "RecurrentTasks",
44
"copyright": "Dmitry Popov, 2016",
55
"packOptions": {
66
"summary": "RecurrentTasks for .NET allows you to run simple recurrent background tasks with specific intervals, without complex frameworks, persistance, etc...",
77
"tags": [ "task", "job", "recurrent", "recurring", "aspnetcore" ],
88
"owners": [ "Dmitry Popov" ],
9-
"releaseNotes": "Initial v3 release",
9+
"releaseNotes": "ITask.BeforeRun, ITask.AfterRunSuccess events added",
1010
"licenseUrl": "https://github.com/justdmitry/RecurrentTasks/blob/master/LICENSE",
1111
"projectUrl": "https://github.com/justdmitry/RecurrentTasks",
1212
"repository": {

0 commit comments

Comments
 (0)