Alveus.JobRunner
0.5.2
dotnet add package Alveus.JobRunner --version 0.5.2
NuGet\Install-Package Alveus.JobRunner -Version 0.5.2
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Alveus.JobRunner" Version="0.5.2" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Alveus.JobRunner" Version="0.5.2" />
<PackageReference Include="Alveus.JobRunner" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Alveus.JobRunner --version 0.5.2
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Alveus.JobRunner, 0.5.2"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Alveus.JobRunner@0.5.2
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Alveus.JobRunner&version=0.5.2
#tool nuget:?package=Alveus.JobRunner&version=0.5.2
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Alveus.JobRunner
A lightweight, AOT-compatible job runner for executing tasks sequentially with support for dynamic job enqueueing, custom contexts, and comprehensive execution callbacks.
Features
- Sequential Execution: Jobs are executed in FIFO order
- Dynamic Job Enqueueing: Jobs can enqueue additional jobs during execution
- Custom Context: Pass custom data to all jobs in the sequence
- Exception Handling: Configure whether to halt or continue on exceptions
- Execution Callbacks: Hook into job lifecycle events
- AOT Compatible: Fully supports Native AOT compilation
- Flexible Job Definition: Define jobs via classes or inline delegates
Installation
dotnet add package Alveus.JobRunner
Quick Start
Using DelegateJob
using Alveus.JobRunner;
var runner = new JobRunner<MyContext>();
// Add jobs using delegates
runner.Enqueue(new DelegateJob<MyContext>(
async (queue, context, ct) =>
{
Console.WriteLine("Job 1 executing");
// Enqueue additional jobs dynamically
queue.Enqueue(new DelegateJob<MyContext>(
async (q, ctx, c) => Console.WriteLine("Job 3 executing"),
"Dynamic Job"
));
},
"Job 1"
));
runner.Enqueue(new DelegateJob<MyContext>(
async (queue, context, ct) => Console.WriteLine("Job 2 executing"),
"Job 2"
));
// Execute all jobs
var context = new MyContext();
await runner.ExecuteAsync(context);
Using Custom Job Classes
using Alveus.JobRunner;
[JobName("Send Email")]
public class SendEmailJob : IJob<EmailContext>
{
public async Task ExecuteAsync(IJobQueue<EmailContext> queue, EmailContext context, CancellationToken cancellationToken)
{
await SendEmailAsync(context.Recipient, context.Message);
// Optionally enqueue follow-up jobs
queue.Enqueue(new LogEmailSentJob());
}
}
var runner = new JobRunner<EmailContext>();
runner.Enqueue(new SendEmailJob());
await runner.ExecuteAsync(new EmailContext
{
Recipient = "user@example.com",
Message = "Hello!"
});
Exception Handling
Halt on Exception (Default)
var runner = new JobRunner<string>();
runner.Enqueue(new DelegateJob<string>(async (q, ctx, ct) => throw new Exception()));
// Throws exception and stops execution
await runner.ExecuteAsync("context", haltOnException: true);
Continue on Exception
var runner = new JobRunner<string>();
runner.Enqueue(new DelegateJob<string>(async (q, ctx, ct) => throw new Exception()));
runner.Enqueue(new DelegateJob<string>(async (q, ctx, ct) => Console.WriteLine("Still executing")));
// Continues executing remaining jobs after exception
await runner.ExecuteAsync("context", haltOnException: false);
Execution Callbacks
OnJobExecuting
var runner = new JobRunner<string>();
runner.OnJobExecuting += context =>
{
Console.WriteLine($"Executing job {context.JobIndex + 1}/{context.TotalJobs}");
if (context.JobName != null)
{
Console.WriteLine($"Job name: {context.JobName}");
}
};
runner.Enqueue(new DelegateJob<string>(async (q, ctx, ct) => { }, "My Job"));
await runner.ExecuteAsync("context");
OnJobException
var runner = new JobRunner<string>();
runner.OnJobException += (context, exception) =>
{
Console.WriteLine($"Job {context.JobIndex} failed: {exception.Message}");
// Log to monitoring service, send alerts, etc.
};
runner.Enqueue(new DelegateJob<string>(async (q, ctx, ct) => throw new Exception("Oops")));
await runner.ExecuteAsync("context", haltOnException: false);
Job Naming
Using JobNameAttribute
[JobName("Process Payment")]
public class ProcessPaymentJob : IJob<PaymentContext>
{
public async Task ExecuteAsync(IJobQueue<PaymentContext> queue, PaymentContext context, CancellationToken cancellationToken)
{
// Process payment
}
}
Using DelegateJob Constructor
runner.Enqueue(new DelegateJob<string>(
async (q, ctx, ct) => { /* work */ },
"My Named Job"
));
Advanced Usage
Dynamic Job Chaining
var runner = new JobRunner<ProcessContext>();
runner.Enqueue(new DelegateJob<ProcessContext>(
async (queue, context, ct) =>
{
var items = await FetchItemsAsync();
// Dynamically enqueue a job for each item
foreach (var item in items)
{
queue.Enqueue(new ProcessItemJob(item));
}
},
"Fetch and Queue Items"
));
await runner.ExecuteAsync(new ProcessContext());
Progress Tracking
var runner = new JobRunner<string>();
var progress = new Progress();
runner.OnJobExecuting += context =>
{
progress.Report(context.JobIndex, context.TotalJobs);
};
// Add jobs...
await runner.ExecuteAsync("context");
Cancellation Support
var runner = new JobRunner<string>();
var cts = new CancellationTokenSource();
// Add jobs...
// Cancel after 5 seconds
cts.CancelAfter(TimeSpan.FromSeconds(5));
try
{
await runner.ExecuteAsync("context", cancellationToken: cts.Token);
}
catch (OperationCanceledException)
{
Console.WriteLine("Execution was cancelled");
}
API Reference
IJobRunner<TContext>
void Enqueue(IJob<TContext> job)- Enqueues a job for executionTask ExecuteAsync(TContext context, bool haltOnException = true, CancellationToken cancellationToken = default)- Executes all enqueued jobsevent JobExecutingCallback<TContext>? OnJobExecuting- Fires before each job executesevent JobExceptionCallback<TContext>? OnJobException- Fires when a job throws an exception
IJob<TContext>
Task ExecuteAsync(IJobQueue<TContext> queue, TContext context, CancellationToken cancellationToken)- Executes the job
JobExecutionContext<TContext>
IJob<TContext> Job- The job being executedstring? JobName- The name of the job (from attribute or constructor)int JobIndex- Zero-based index of the jobint TotalJobs- Total number of jobs in the queue
License
Refer to LICENSE document for license information.
Contributing
Copyright (c) Alveus Dev (https://alveus.dev). All rights reserved.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.