<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/building-a-scheduled-task-in-asp-net-core-standard-2-0-sncezji7i" -->

---
title: Building a scheduled task in ASP.NET Core/Standard 2.0
description: A simple cron-based task scheduler is built on top of ASP.NET Core 2.0's IHostedService interface, inspired by Spring's @Scheduled annotation seen in a Kotlin...
canonical: https://daily.dev/posts/building-a-scheduled-task-in-asp-net-core-standard-2-0-sncezji7i
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Building a scheduled task in ASP.NET Core/Standard 2.0 | daily.dev
og:description: A simple cron-based task scheduler is built on top of ASP.NET Core 2.0's IHostedService interface, inspired by Spring's @Scheduled annotation seen in a Kotlin...
og:url: https://daily.dev/posts/building-a-scheduled-task-in-asp-net-core-standard-2-0-sncezji7i
og:image: https://api.daily.dev/og/posts/SncezJi7I.png
og:image:alt: Building a scheduled task in ASP.NET Core/Standard 2.0
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Building a scheduled task in ASP.NET Core/Standard 2.0

**[Maarten Balliauw](https://daily.dev/sources/maartenballiauw)** · 8 min read · 0 upvotes · 0 comments

## Summary

A simple cron-based task scheduler is built on top of ASP.NET Core 2.0's IHostedService interface, inspired by Spring's @Scheduled annotation seen in a Kotlin Slack bot. The implementation defines an IScheduledTask interface with a cron Schedule property and an ExecuteAsync method, registers tasks via dependency injection, and uses a SchedulerHostedService that checks and runs due tasks every minute via TaskFactory.StartNew() to avoid blocking the scheduler loop. A worked example fetches a daily quote from an external API every six hours and exposes unobserved task exception handling. Full sample code is provided as a downloadable zip.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://blog.maartenballiauw.be/posts/2017-08-01-building-a-scheduled-cache-updater-in-aspnet-core-2>

## Questions this post answers

### How do I build a cron-based scheduled task system using IHostedService in ASP.NET Core 2.0?

Define an IScheduledTask interface exposing a cron Schedule string and an ExecuteAsync method, register task implementations via services.AddSingleton in Startup.cs, then build a SchedulerHostedService that loops every minute checking a parsed cron schedule against the current time and invokes due tasks with TaskFactory.StartNew() so a long-running task never blocks the scheduler loop itself.

_See how daily.dev surfaces practical ASP.NET Core background task patterns like this one._

### Why should I avoid simply awaiting scheduled task execution directly inside a background scheduler loop?

Awaiting a task directly inside the scheduler loop risks the whole scheduler getting stuck if that task never returns or runs long, since the loop can't move on to check or trigger other scheduled tasks. Spawning each due task with TaskFactory.StartNew() instead lets the scheduler keep ticking every minute regardless of individual task duration, with exceptions captured via a custom UnobservedTaskException handler.

_Developers designing resilient background jobs can find similar architecture trade-offs on daily.dev._

## Similar posts on daily.dev

- [ASP.NET Core Scheduler Features Every Developer Should Know](https://daily.dev/posts/asp-net-core-scheduler-features-every-developer-should-know-rdg3ypdhw) · Syncfusion · 4 upvotes · 0 comments
- [Laravel Task Scheduling & Automation: Simplify Cron Jobs with the Scheduler](https://daily.dev/posts/laravel-task-scheduling-automation-simplify-cron-jobs-with-the-scheduler-nqdiov7wv) · DEV · 2 upvotes · 0 comments
- [I stopped opening Task Scheduler after discovering VS Code's hidden automation layer](https://daily.dev/posts/i-stopped-opening-task-scheduler-after-discovering-vs-code-s-hidden-automation-layer-s9rgh2ncf) · XDA Developers · 0 upvotes · 0 comments
- [The Laravel Scheduler Under the Hood](https://daily.dev/posts/the-laravel-scheduler-under-the-hood-dgtbvlorx) · W endell Adriel · 5 upvotes · 0 comments

---

Tags: [#c#](https://daily.dev/tags/c#), [#aspnet](https://daily.dev/tags/aspnet)

[View this post on daily.dev](https://daily.dev/posts/building-a-scheduled-task-in-asp-net-core-standard-2-0-sncezji7i)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Building a scheduled task in ASP.NET Core/Standard 2.0","url":"https://daily.dev/posts/building-a-scheduled-task-in-asp-net-core-standard-2-0-sncezji7i","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/building-a-scheduled-task-in-asp-net-core-standard-2-0-sncezji7i"},"datePublished":"2026-10-04T13:04:25.945Z","dateModified":"2026-10-04T13:05:48.400Z","description":"A simple cron-based task scheduler is built on top of ASP.NET Core 2.0's IHostedService interface, inspired by Spring's @Scheduled annotation seen in a Kotlin...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/677970b42cf700cc655ed89673e92438?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/677970b42cf700cc655ed89673e92438?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Maarten Balliauw","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Maarten Balliauw","logo":"https://media.daily.dev/image/upload/s--rOTg3VYO--/f_auto,q_auto/v1791119043/logos/maartenballiauw?_a=BAMAMicg0","url":"https://daily.dev/sources/maartenballiauw"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/building-a-scheduled-task-in-asp-net-core-standard-2-0-sncezji7i","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"c#,aspnet","timeRequired":"PT8M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Maarten Balliauw","item":"https://daily.dev/sources/maartenballiauw"},{"@type":"ListItem","position":3,"name":"Building a scheduled task in ASP.NET Core/Standard 2.0"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/building-a-scheduled-task-in-asp-net-core-standard-2-0-sncezji7i#faq","mainEntity":[{"@type":"Question","name":"How do I build a cron-based scheduled task system using IHostedService in ASP.NET Core 2.0?","acceptedAnswer":{"@type":"Answer","text":"Define an IScheduledTask interface exposing a cron Schedule string and an ExecuteAsync method, register task implementations via services.AddSingleton in Startup.cs, then build a SchedulerHostedService that loops every minute checking a parsed cron schedule against the current time and invokes due tasks with TaskFactory.StartNew() so a long-running task never blocks the scheduler loop itself. See how daily.dev surfaces practical ASP.NET Core background task patterns like this one."}},{"@type":"Question","name":"Why should I avoid simply awaiting scheduled task execution directly inside a background scheduler loop?","acceptedAnswer":{"@type":"Answer","text":"Awaiting a task directly inside the scheduler loop risks the whole scheduler getting stuck if that task never returns or runs long, since the loop can't move on to check or trigger other scheduled tasks. Spawning each due task with TaskFactory.StartNew() instead lets the scheduler keep ticking every minute regardless of individual task duration, with exceptions captured via a custom UnobservedTaskException handler. Developers designing resilient background jobs can find similar architecture trade-offs on daily.dev."}}]}
```

