Installation
This guide will walk you through installing and configuring TickerQ in your .NET application.
Package Manager Console
Install-Package TickerQ.NET CLI
dotnet add package TickerQPackageReference
<PackageReference Include="TickerQ" Version="8.0.0-beta.1" />Prerequisites
- .NET 8.0 or later
- Visual Studio 2022, Rider, or VS Code with C# extension
Optional Packages
Add these based on your requirements:
Entity Framework Core
For database persistence:
dotnet add package TickerQ.EntityFrameworkCoreDashboard
For the real-time web UI:
dotnet add package TickerQ.DashboardRedis
For multi-node coordination:
dotnet add package TickerQ.Caching.StackExchangeRedisOpenTelemetry
For distributed tracing:
dotnet add package TickerQ.Instrumentation.OpenTelemetryBasic Setup
Minimal Configuration
The simplest setup requires just two lines:
using TickerQ.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTickerQ(); // Register services
var app = builder.Build();
app.UseTickerQ(); // Activate job processor
app.Run();That's it! TickerQ is now ready to use.
Verifying Installation
To verify TickerQ is working correctly:
- Check Services are Registered
// In Program.cs after AddTickerQ()
var timeManager = app.Services.GetService<ITimeTickerManager<TimeTickerEntity>>();
var cronManager = app.Services.GetService<ICronTickerManager<CronTickerEntity>>();
if (timeManager != null && cronManager != null)
{
Console.WriteLine("TickerQ services registered successfully");
}- Test Job Execution
Create a simple test job:
public class TestJobs
{
[TickerFunction("TestJob")]
public async Task TestJob(
TickerFunctionContext context,
CancellationToken cancellationToken)
{
Console.WriteLine($"TickerQ is working! Job ID: {context.Id}");
}
}
// Schedule it
await _timeTickerManager.AddAsync(new TimeTickerEntity
{
Function = "TestJob",
ExecutionTime = DateTime.UtcNow.AddSeconds(5)
});- Check Application Logs
Look for TickerQ initialization messages:
- No errors during service registration
- Background services started successfully
- Jobs executing (when scheduled)
Configuration Options
For production use, configure options via ConfigureScheduler:
builder.Services.AddTickerQ(options =>
{
// Configure scheduler options
options.ConfigureScheduler(scheduler =>
{
scheduler.MaxConcurrency = 10; // Maximum concurrent worker threads
scheduler.NodeIdentifier = "production-server-01"; // Unique node identifier
scheduler.IdleWorkerTimeOut = TimeSpan.FromMinutes(1); // Idle worker timeout
scheduler.SchedulerTimeZone = TimeZoneInfo.Utc; // Timezone for scheduling
});
// Set exception handler
options.SetExceptionHandler<MyExceptionHandler>();
});See: Configuration Reference for all available options.
Advanced Configuration
Start Mode
Control when TickerQ starts processing jobs:
// Immediate start (default) - starts processing as soon as UseTickerQ is called
app.UseTickerQ(TickerQStartMode.Immediate);
// Manual start - requires explicit start
app.UseTickerQ(TickerQStartMode.Manual);Integrations
Entity Framework Core
TickerQ provides a lightweight built-in TickerQDbContext designed specifically for TickerQ jobs. This is the recommended approach for most scenarios:
using TickerQ.DependencyInjection;
using TickerQ.EntityFrameworkCore.DependencyInjection;
using TickerQ.EntityFrameworkCore.DbContextFactory;
builder.Services.AddTickerQ(options =>
{
options.AddOperationalStore(efOptions =>
{
// Use built-in TickerQDbContext with connection string
efOptions.UseTickerQDbContext<TickerQDbContext>(optionsBuilder =>
{
optionsBuilder.UseNpgsql("Server=localhost;Port=5432;Database=TickerQ;User Id=postgres;Password=postgres;",
cfg =>
{
cfg.EnableRetryOnFailure(3, TimeSpan.FromSeconds(5), ["40P01"]);
});
});
// Optional: Configure pool size
efOptions.SetDbContextPoolSize(34);
});
});For SQL Server:
efOptions.UseTickerQDbContext<TickerQDbContext>(optionsBuilder =>
{
optionsBuilder.UseSqlServer("Server=localhost;Database=TickerQ;Integrated Security=true;");
});Alternative: Use Your Application DbContext
If you prefer to integrate with your existing application DbContext:
using TickerQ.DependencyInjection;
using TickerQ.EntityFrameworkCore.DependencyInjection;
builder.Services.AddTickerQ(options =>
{
options.AddOperationalStore<MyApplicationDbContext>(efOptions =>
{
efOptions.UseApplicationDbContext<MyApplicationDbContext>(ConfigurationType.UseModelCustomizer);
});
});Dashboard
using TickerQ.DependencyInjection;
using TickerQ.Dashboard.DependencyInjection;
builder.Services.AddTickerQ(options =>
{
options.AddDashboard(dashboardOptions =>
{
// Set base path (default: /tickerq/dashboard)
dashboardOptions.SetBasePath("/tickerq/dashboard");
// Configure authentication (see Dashboard Authentication)
dashboardOptions.WithBasicAuth("admin", "password");
// OR
dashboardOptions.WithApiKey("your-api-key");
// OR
dashboardOptions.WithHostAuthentication();
});
});Complete Setup
Here's a production-ready example with all features enabled:
using TickerQ.DependencyInjection;
using TickerQ.EntityFrameworkCore.DependencyInjection;
using TickerQ.EntityFrameworkCore.DbContextFactory;
using TickerQ.Dashboard.DependencyInjection;
using TickerQ.Caching.StackExchangeRedis.DependencyInjection;
using TickerQ.Instrumentation.OpenTelemetry.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
// Add TickerQ with all features
builder.Services.AddTickerQ(options =>
{
// Core scheduler configuration
options.ConfigureScheduler(schedulerOptions =>
{
schedulerOptions.MaxConcurrency = 8;
schedulerOptions.NodeIdentifier = "production-node-01";
schedulerOptions.IdleWorkerTimeOut = TimeSpan.FromMinutes(1);
schedulerOptions.FallbackIntervalChecker = TimeSpan.FromMinutes(1);
schedulerOptions.SchedulerTimeZone = TimeZoneInfo.Local;
});
// Exception handling
options.SetExceptionHandler<MyExceptionHandler>();
// Entity Framework persistence (using built-in TickerQDbContext)
options.AddOperationalStore(efOptions =>
{
efOptions.UseTickerQDbContext<TickerQDbContext>(optionsBuilder =>
{
optionsBuilder.UseNpgsql("Server=localhost;Port=5432;Database=TickerQ;User Id=postgres;Password=postgres;",
cfg =>
{
cfg.EnableRetryOnFailure(3, TimeSpan.FromSeconds(5), ["40P01"]);
});
});
efOptions.SetDbContextPoolSize(34);
});
// Redis for multi-node coordination
options.AddStackExchangeRedis(redisOptions =>
{
redisOptions.Configuration = "localhost:6379";
redisOptions.NodeHeartbeatInterval = TimeSpan.FromMinutes(1);
});
// Dashboard
options.AddDashboard(dashboardOptions =>
{
dashboardOptions.SetBasePath("/tickerq/dashboard");
dashboardOptions.WithBasicAuth("admin", "secure-password");
});
// OpenTelemetry instrumentation
options.AddOpenTelemetryInstrumentation();
});
var app = builder.Build();
// Configure middleware
app.UseTickerQ();
app.Run();Version Management
Important
All TickerQ packages are versioned together. Always update all packages to the same version.
dotnet add package TickerQ --version 8.0.0
dotnet add package TickerQ.EntityFrameworkCore --version 8.0.0
dotnet add package TickerQ.Dashboard --version 8.0.0What's Next?
- Quick Start - Get running in 5 minutes
- Job Types - Learn about TimeTicker and CronTicker
- Complete Example - See a full working example
