
Research
/Security News
60 Malicious Ruby Gems Used in Targeted Credential Theft Campaign
A RubyGems malware campaign used 60 malicious packages posing as automation tools to steal credentials from social media and marketing tool users.
CronScheduler.Extensions
Advanced tools
A powerful Cron-based Scheduler for .NET Core applications, optimized for Kubernetes/Docker and Windows Services. A lightweight alternative to Quartz Scheduler and HangFire.
Supply Chain Security
Vulnerability
Quality
Maintenance
License
Note: Pre-release packages are distributed via feedz.io.
Unlock the Power of Simplified Cron Scheduling in Your .NET Core Apps
Are you tired of complex scheduling libraries holding you back from building scalable and efficient applications? Look no further! Introducing CronScheduler, a lightweight and easy-to-use library designed specifically for .NET Core IHost
or IWebHost
.
Built with the KISS principle in mind, CronScheduler is a simplified alternative to Quartz Scheduler and its alternatives. With CronScheduler, you can easily schedule tasks using cron syntax and operate within any .NET Core GenericHost IHost
, making setup and configuration a breeze.
But that's not all! We've also introduced IStartupJob, allowing for async initialization of critical processes before the host is ready to start. This means you can ensure your application is properly initialized and running smoothly, even in complex Kubernetes environments.
Benefits:
IHost
or IWebHost
Join the CronScheduler community today and start simplifying your application's scheduling needs!
Please refer to Migration Guide for the upgrade.
If you like or are using this project to learn or start your solution, please give it a star. Thanks!
AspNetCore
hosting .NET CLI dotnet add package CronScheduler.AspNetCore
IHost
hosting .NET CLI dotnet add package CronScheduler.Extensions
This library supports up to 5 seconds job intervals in the Crontab format thank to HangfireIO/Cronos library.
You can use https://crontab-generator.org/ to generated needed job/task schedule.
Cron expression is a mask to define fixed times, dates and intervals. The mask consists of second (optional), minute, hour, day-of-month, month and day-of-week fields. All of the fields allow you to specify multiple values, and any given date/time will satisfy the specified Cron expression, if all the fields contain a matching value.
Allowed values Allowed special characters Comment
┌───────────── second (optional) 0-59 * , - /
│ ┌───────────── minute 0-59 * , - /
│ │ ┌───────────── hour 0-23 * , - /
│ │ │ ┌───────────── day of month 1-31 * , - / L W ?
│ │ │ │ ┌───────────── month 1-12 or JAN-DEC * , - /
│ │ │ │ │ ┌───────────── day of week 0-6 or SUN-SAT * , - / # L ? Both 0 and 7 means SUN
│ │ │ │ │ │
* * * * * *
CronScheduler
with new Microsoft .NET Core Workers TemplateCronScheduler
with AspNetCore applications.There are two ways that options and jobs can be registered within the Scheduler Jobs.
IConfiguration
This job registration is assuming that the name of the job and options name are the same.
services.AddScheduler(ctx =>
{
ctx.AddJob<TestJob>();
});
services.AddScheduler(ctx =>
{
var jobName1 = "TestJob1";
ctx.AddJob(
sp =>
{
var options = sp.GetRequiredService<IOptionsMonitor<SchedulerOptions>>().Get(jobName1);
return new TestJobDup(options, mockLoggerTestJob.Object);
},
options =>
{
options.CronSchedule = "*/5 * * * * *";
options.RunImmediately = true;
},
jobName: jobName1);
var jobName2 = "TestJob2";
ctx.AddJob(
sp =>
{
var options = sp.GetRequiredService<IOptionsMonitor<SchedulerOptions>>().Get(jobName2);
return new TestJobDup(options, mockLoggerTestJob.Object);
}, options =>
{
options.CronSchedule = "*/5 * * * * *";
options.RunImmediately = true;
},
jobName: jobName2);
});
public class TorahQuoteJob : IScheduledJob
{
private readonly TorahQuoteJobOptions _options;
private readonly TorahVerses _torahVerses;
private readonly TorahService _service;
/// <summary>
/// Initializes a new instance of the <see cref="TorahQuoteJob"/> class.
/// </summary>
/// <param name="options"></param>
/// <param name="service"></param>
/// <param name="torahVerses"></param>
public TorahQuoteJob(
IOptionsMonitor<TorahQuoteJobOptions> options,
TorahService service,
TorahVerses torahVerses)
{
_options = options.Get(Name);
_service = service ?? throw new ArgumentNullException(nameof(service));
_torahVerses = torahVerses ?? throw new ArgumentNullException(nameof(torahVerses));
}
// job name and options name must match.
public string Name { get; } = nameof(TorahQuoteJob);
public async Task ExecuteAsync(CancellationToken cancellationToken)
{
var index = new Random().Next(_options.Verses.Length);
var exp = _options.Verses[index];
_torahVerses.Current = await _service.GetVersesAsync(exp, cancellationToken);
}
}
Then register this service within the Program.cs
:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddScheduler(builder =>
{
builder.Services.AddSingleton<TorahVerses>();
builder.Services
.AddHttpClient<TorahService>()
.AddTransientHttpErrorPolicy(p => p.RetryAsync());
builder.AddJob<TorahQuoteJob, TorahQuoteJobOptions>();
builder.Services.AddScoped<UserService>();
builder.AddJob<UserJob, UserJobOptions>();
builder.AddUnobservedTaskExceptionHandler(sp =>
{
var logger = sp.GetRequiredService<ILoggerFactory>().CreateLogger("CronJobs");
return (sender, args) =>
{
logger?.LogError(args.Exception?.Message);
args.SetObserved();
};
});
});
builder.Services.AddBackgroundQueuedService(applicationOnStopWaitForTasksToComplete: true);
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddStartupJob<SeedDatabaseStartupJob>();
builder.Services.AddStartupJob<TestStartupJob>();
builder.Logging.AddConsole();
builder.Logging.AddDebug();
builder.Logging.AddConfiguration(builder.Configuration.GetSection("Logging"));
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseRouting();
app.MapControllers();
app.MapDefaultControllerRoute();
app.MapRazorPages();
await app.RunStartupJobsAsync();
await app.RunAsync();
IStartupJobs
to assist with async jobs initialization before the application startsThere are many case scenarios to use StartupJobs for the IWebHost
interface or IGenericHost
. The most common case scenario is to make sure that the database is created and updated.
This library makes it possible by simply doing the following:
Program.cs
file add the following:var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddStartupJob<SeedDatabaseStartupJob>();
builder.Services.AddStartupJob<TestStartupJob>();
var app = builder.Build();
// Configure the HTTP request pipeline.
await app.RunStartupJobsAsync();
await app.RunAsync();
In some instances of the application the need for queuing of the tasks is required. In order to enable this add the following in Startup.cs
.
services.AddBackgroundQueuedService();
Then add sample async task to be executed by the Queued Hosted Service.
public class MyService
{
private readonly IBackgroundTaskQueue _taskQueue;
public MyService(IBackgroundTaskQueue taskQueue)
{
_taskQueue = taskQueue;
}
public void RunTask()
{
_taskQueue.QueueBackgroundWorkItem(async (token)=>
{
// run some task
await Task.Delay(TimeSpan.FromSeconds(10), token);
}});
}
}
FAQs
A powerful Cron-based Scheduler for .NET Core applications, optimized for Kubernetes/Docker and Windows Services. A lightweight alternative to Quartz Scheduler and HangFire.
We found that cronscheduler.extensions demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
/Security News
A RubyGems malware campaign used 60 malicious packages posing as automation tools to steal credentials from social media and marketing tool users.
Security News
The CNA Scorecard ranks CVE issuers by data completeness, revealing major gaps in patch info and software identifiers across thousands of vulnerabilities.
Research
/Security News
Two npm packages masquerading as WhatsApp developer libraries include a kill switch that deletes all files if the phone number isn’t whitelisted.