andresharpe/dotbot/setup-background-job

Claude Code and agent skill by andresharpe/dotbot

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Install

npx vskill@latest install andresharpe/dotbot/setup-background-job

SKILL.md

Setup Background Job

Guide for creating scheduled background jobs using Quartz.NET.

When to Use

  • Periodic tasks (email polling, data sync, cleanup)
  • Scheduled operations (daily reports, reminders)
  • Recurring background processing
  • Cron-based job scheduling

Job Implementation

csharp
public class EmailPollingJob : IJob
{
private readonly IEmailService _emailService;
private readonly ILogger<EmailPollingJob> _logger;
public EmailPollingJob(IEmailService emailService, ILogger<EmailPollingJob> logger)
{
_emailService = emailService;
_logger = logger;
}
public async Task Execute(IJobExecutionContext context)
{
_logger.LogInformation("Email polling job started");
try
{
await _emailService.PollNewEmails();
_logger.LogInformation("Email polling completed successfully");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error polling emails");
throw new JobExecutionException(ex, refireImmediately: false);
}
}
}

Job Registration

csharp
// In Program.cs or Startup.cs
services.AddQuartz(q =>
{
q.UseMicrosoftDependencyInjectionJobFactory();
// Define the job
var jobKey = new JobKey("EmailPollingJob");
q.AddJob<EmailPollingJob>(opts => opts.WithIdentity(jobKey));
// Create a trigger
q.AddTrigger(opts => opts
.ForJob(jobKey)
.WithIdentity("EmailPollingTrigger")
.WithCronSchedule("0 */5 * * * ?")); // Every 5 minutes
});
services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);

Cron Expressions

Common patterns:

0 0 8 * * ? - Every day at 8:00 AM
0 */5 * * * ? - Every 5 minutes
0 30 17 * * ? - Every day at 5:30 PM
0 0 0 ? * SUN - Every Sunday at midnight
0 0 * * * ? - Every hour
0 */30 * * * ? - Every 30 minutes
0 0 1 1 * ? - First day of month at 1:00 AM

Format: second minute hour day-of-month month day-of-week

Job Data

Pass parameters to jobs:

csharp
// When scheduling
q.AddTrigger(opts => opts
.ForJob(jobKey)
.UsingJobData("userId", "user123")
.UsingJobData("maxItems", 50)
.WithCronSchedule("0 0 * * * ?"));
// In job
public async Task Execute(IJobExecutionContext context)
{
var userId = context.MergedJobDataMap.GetString("userId");
var maxItems = context.MergedJobDataMap.GetInt("maxItems");
// ... use parameters
}

Error Handling

csharp
public async Task Execute(IJobExecutionContext context)
{
try
{
await DoWork();
}
catch (TransientException ex)
{
// Retry immediately
throw new JobExecutionException(ex, refireImmediately: true);
}
catch (Exception ex)
{
// Log and don't retry
_logger.LogError(ex, "Job failed");
throw new JobExecutionException(ex, refireImmediately: false);
}
}

Job Control

Pause/Resume
csharp
await scheduler.PauseJob(jobKey);
await scheduler.ResumeJob(jobKey);
Trigger Immediately
csharp
await scheduler.TriggerJob(jobKey);
Remove Job
csharp
await scheduler.DeleteJob(jobKey);

Best Practices

  • Dependency Injection - Use DI for services
  • Idempotent - Jobs should be safe to run multiple times
  • Logging - Log start, completion, and errors
  • Timeout - Consider job execution timeout
  • Overlap - Prevent concurrent executions if needed
  • Configuration - Use appsettings for schedules

Preventing Concurrent Execution

csharp
[DisallowConcurrentExecution]
public class ExclusiveJob : IJob
{
// Only one instance runs at a time
}

Job Persistence

For production, use persistent job store:

csharp
services.AddQuartz(q =>
{
q.UsePersistentStore(s =>
{
s.UseSqlite(sqlite =>
{
sqlite.ConnectionString = "Data Source=quartz.db";
});
s.UseJsonSerializer();
});
});

Common Pitfalls

  • ❌ Not handling exceptions properly
  • ❌ Long-running jobs blocking other jobs
  • ❌ Not using DisallowConcurrentExecution when needed
  • ❌ Hardcoding schedules instead of configuration
  • ❌ Not logging job execution
  • ❌ Forgetting to register job with DI

Checklist

  • [ ] Job class implements IJob
  • [ ] Dependencies injected via constructor
  • [ ] Error handling implemented
  • [ ] Logging added (start/complete/error)
  • [ ] Job registered with Quartz
  • [ ] Trigger configured with correct schedule
  • [ ] Cron expression tested
  • [ ] DisallowConcurrentExecution if needed
  • [ ] Configuration externalized

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
50
Repository forks
24
7-day trend score
20

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/andresharpe/dotbot/setup-background-job/badge)](https://verified-skill.com/skills/andresharpe/dotbot/setup-background-job)

Something wrong with this skill or its page? Tell us.