{"id":32958245,"url":"https://github.com/NCronJob-Dev/NCronJob","last_synced_at":"2025-11-16T17:02:02.452Z","repository":{"id":228195265,"uuid":"773369754","full_name":"NCronJob-Dev/NCronJob","owner":"NCronJob-Dev","description":"A Job Scheduler sitting on top of IHostedService in dotnet.","archived":false,"fork":false,"pushed_at":"2025-11-15T21:47:57.000Z","size":4931,"stargazers_count":187,"open_issues_count":38,"forks_count":14,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-11-15T23:27:30.579Z","etag":null,"topics":["cronjob","csharp","dotnet","job-scheduler","jobscheduler","minimal-api"],"latest_commit_sha":null,"homepage":"https://docs.ncronjob.dev/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NCronJob-Dev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-03-17T13:38:02.000Z","updated_at":"2025-11-15T21:48:00.000Z","dependencies_parsed_at":"2024-04-15T21:25:15.917Z","dependency_job_id":"6c1d78c0-a0fe-4bc3-a524-3e5afd12da56","html_url":"https://github.com/NCronJob-Dev/NCronJob","commit_stats":null,"previous_names":["linkdotnet/ncronjob","ncronjob-dev/ncronjob"],"tags_count":56,"template":false,"template_full_name":null,"purl":"pkg:github/NCronJob-Dev/NCronJob","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NCronJob-Dev%2FNCronJob","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NCronJob-Dev%2FNCronJob/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NCronJob-Dev%2FNCronJob/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NCronJob-Dev%2FNCronJob/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NCronJob-Dev","download_url":"https://codeload.github.com/NCronJob-Dev/NCronJob/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NCronJob-Dev%2FNCronJob/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":284742551,"owners_count":27056072,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-16T02:00:05.974Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cronjob","csharp","dotnet","job-scheduler","jobscheduler","minimal-api"],"created_at":"2025-11-12T23:00:34.016Z","updated_at":"2025-11-16T17:02:02.446Z","avatar_url":"https://github.com/NCronJob-Dev.png","language":"C#","funding_links":[],"categories":["Scheduling","Identifiers"],"sub_categories":["GUI - other"],"readme":"\u003ch1 align=\"center\"\u003eNCronJob\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"/assets/logo_small.png\" alt=\"logo\" width=\"120px\" height=\"120px\"/\u003e\n  \u003cbr\u003e\n  \u003cem\u003eScheduling made easy\u003c/em\u003e\n  \u003cbr\u003e\n\u003c/p\u003e\n\n\n[![.NET](https://github.com/NCronJob-Dev/NCronJob/actions/workflows/dotnet.yml/badge.svg)](https://github.com/NCronJob-Dev/NCronJob/actions/workflows/dotnet.yml)\n[![NuGet](https://img.shields.io/nuget/dt/NCronJob.svg)](https://www.nuget.org/packages/NCronJob)\n[![NuGet](https://img.shields.io/nuget/vpre/NCronJob.svg)](https://www.nuget.org/packages/NCronJob)\n[![Coverage](https://codecov.io/gh/NCronJob-Dev/NCronJob/graph/badge.svg?token=HM8G8TCYUC)](https://codecov.io/gh/NCronJob-Dev/NCronJob)\n\n# NCronJob\n\nA Job Scheduler sitting on top of `IHostedService` in .NET.\n\nOften, one finds oneself between the simplicity of `BackgroundService`/`IHostedService` and the complexity of\na full-blown scheduler like `Hangfire` or `Quartz`.\nThis library aims to fill that gap by providing a simple and easy-to-use job scheduler that can be used in any .NET\napplication and feels \"native\".\n\nThere's no need to set up a database—just schedule your tasks right away! The library provides two ways of scheduling\njobs:\n\n1. Instant jobs - Run a job immediately (or with a small delay, or at a specific date and time).\n2. Cron jobs - Schedule a job using a cron expression.\n\nThe whole documentation can be found here: [NCronJob Documentation](https://docs.ncronjob.dev/)\n\n- [NCronJob](#ncronjob)\n  - [Features](#features)\n  - [Not features](#not-features)\n  - [Short example](#short-example)\n    - [Minimal Job API](#minimal-job-api)\n    - [Via the `IJob` interface](#via-the-ijob-interface)\n  - [Triggering an instant job](#triggering-an-instant-job)\n  - [Running a Job at Startup](#running-a-job-at-startup)\n  - [Defining Job Dependencies](#defining-job-dependencies)\n  - [Support \\\u0026 Contributing](#support--contributing)\n\n\n## Features\n\n- [x] The ability to schedule jobs using a cron expression.\n- [x] The ability to instantly run a job.\n- [x] Parameterized jobs - Instant as well as cron jobs!\n- [x] Integration with ASP.NET - Access your DI container like you would in any other service.\n- [x] Get notified when a job is done (either successfully or with an error).\n- [x] Retries - If a job fails, it will be retried.\n- [x] The job scheduler supports TimeZones. Defaults to UTC time.\n- [x] Minimal API for Jobs - Implement jobs in a one-liner.\n- [x] Startup jobs - Run a job when the application starts.\n- [x] Define job dependencies - trigger another job if one was successful or faulted!\n- [x] Add, remove, and update jobs at runtime.\n\n## Not features\n\nAs this is a simple scheduler, some features are not included by design. If you need these features, you might want to\nlook into a more advanced scheduler like `Hangfire` or `Quartz`.\n\n- [ ] Job persistence - Jobs are not persisted between restarts of the application.\n- [ ] Job history - There is no history of jobs that have been run.\n- [ ] Progress state - There is no way to track the progress of a job. The library supports notifying when a job is\n  done, but not the progress of the job itself.\n\n## Short example\n\nThere are two ways to define a job.\n\n### Minimal Job API\n\nYou can use this library in a simple one-liner:\n```csharp\nbuilder.Services.AddNCronJob((ILoggerFactory factory, TimeProvider timeProvider) =\u003e\n{\n    var logger = factory.CreateLogger(\"My Anonymous Job\");\n    logger.LogInformation(\"Hello World - The current date and time is {Time}\", timeProvider.GetLocalNow());\n}, \"*/5 * * * * *\");\n\nvar app = builder.Build();\nawait app.UseNCronJobAsync();\napp.Run();\n```\n\nWith this simple lambda, you can define a job that runs every 5 seconds. Pass in all dependencies, just like you would with a Minimal API.\n\n### Via the `IJob` interface\n\n1. Import the namespace (or let your IDE do the dirty work)\n\n```csharp\nusing NCronJob;\n```\n\n2. Create a job\n\n```csharp\npublic class PrintHelloWorld : IJob\n{\n    private readonly ILogger\u003cPrintHelloWorld\u003e logger;\n\n    public PrintHelloWorld(ILogger\u003cPrintHelloWorld\u003e logger)\n    {\n        this.logger = logger;\n    }\n\n    public Task RunAsync(IJobExecutionContext context, CancellationToken token)\n    {\n        logger.LogInformation(\"Hello World\");\n        logger.LogInformation(\"Parameter: {Parameter}\", context.Parameter);\n\n        return Task.CompletedTask;\n    }\n}\n```\n\n3. Register the NCronJob and the job in your `Program.cs`\n\n```csharp\nbuilder.Services.AddNCronJob(options =\u003e\n    options.AddJob\u003cPrintHelloWorld\u003e(j =\u003e \n    {\n        // Every minute and optional parameter\n        j.WithCronExpression(\"* * * * *\")\n         .WithParameter(\"Hello World\");\n    }));\n```\n\n4. Run your application and see the magic happen!\n\n## Triggering an instant job\n\nIf the need arises and you want to trigger a job instantly, you can do so:\n\n```csharp\npublic class MyService\n{\n  private readonly IInstantJobRegistry jobRegistry;\n  \n  public MyService(IInstantJobRegistry jobRegistry) =\u003e this.jobRegistry = jobRegistry;\n\n  public void MyMethod() =\u003e jobRegistry.RunInstantJob\u003cMyJob\u003e(\"I am an optional parameter\");\n    \n  // Alternatively, you can also run an anonymous job\n  public void MyOtherMethod() =\u003e jobRegistry.RunInstantJob((MyOtherService service) =\u003e service.Do());\n}\n```\n\n## Running a Job at Startup\n\nIf you want a job to run when the application starts, you can configure it to run at startup using the `RunAtStartup` configuration method. Here is an example:\n\n```csharp\nbuilder.Services.AddNCronJob(options =\u003e\n{\n    options.AddJob\u003cMyJob\u003e(j =\u003e j.RunAtStartup());\n});\n\nvar app = builder.Build();\n// Here the startup jobs will be executed\nawait app.UseNCronJobAsync();\napp.Run();\n```\n\nIn this example, the job of type 'MyJob' will be executed as soon as the application starts. This is\nuseful for tasks that need to run immediately upon application startup, such as initial data loading or cleanup tasks.\n\n## Defining Job Dependencies\n\nFirst you need to import data and then transform it? Well, but how do you make sure that the data is imported before you transform it? Sure, you could just give a delay, but what if the import takes longer than expected? This is where job dependencies come in handy!\n\n```csharp\nbuilder.Services.AddNCronJob(options =\u003e\n{\n    options.AddJob\u003cImportData\u003e(p =\u003e p.WithCronExpression(\"0 0 * * *\")\n     .ExecuteWhen(\n        success: s =\u003e s.RunJob\u003cTransformData\u003e(\"Optional Parameter\"),\n        faulted: s =\u003e s.RunJob\u003cNotify\u003e(\"Another Optional Parameter\"));\n});\n```\n\nYou just want to trigger a service and don't want to define a whole new job? No problem! The Minimal API is available here as well:\n\n```csharp\nbuilder.Services.AddNCronJob(options =\u003e\n{\n    options.AddJob\u003cImportData\u003e(p =\u003e p.WithCronExpression(\"0 0 * * *\")\n     .ExecuteWhen(\n        success: s =\u003e s.RunJob(async (ITransformer transformer) =\u003e await transformer.TransformDataAsync()),\n        faulted: s =\u003e s.RunJob(async (INotificationService notifier) =\u003e await notifier.NotifyAsync())\n});\n```\n\n## Support \u0026 Contributing\n\nThanks to all [contributors](https://github.com/NCronJob-Dev/NCronJob/graphs/contributors) and people who are creating\nbug reports and valuable input:\n\n\u003ca href=\"https://github.com/NCronJob-Dev/NCronJob/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=NCronJob-Dev/NCronJob\" alt=\"Supporters\" /\u003e\n\u003c/a\u003e\n\nIf you have any questions or suggestions, feel free to open a new issue or pull request.\nDo you want to contribute? Great! We have a predefined codespace for you to get started right away! With that you don't need any local setup and can start right away!\nEither coding or updating the documentation - everything is set and done for you!\n\n[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/NCronJob-Dev/NCronJob?quickstart=1)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNCronJob-Dev%2FNCronJob","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FNCronJob-Dev%2FNCronJob","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNCronJob-Dev%2FNCronJob/lists"}