When you need to execute periodic tasks like calling a URL endpoint (http://myapp/BackgroundTask/Run
) in an MVC application, .NET provides several native solutions before considering third-party libraries.
The simplest approach is using Windows Task Scheduler combined with a PowerShell script:
# Save this as RunBackgroundTask.ps1
Invoke-WebRequest -Uri "http://myapp/BackgroundTask/Run" -UseDefaultCredentials
Then create a scheduled task that runs daily using:
# Command to create the task
$Action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-File C:\Path\To\RunBackgroundTask.ps1"
$Trigger = New-ScheduledTaskTrigger -Daily -At 3am
Register-ScheduledTask -TaskName "AD Sync Task" -Action $Action -Trigger $Trigger -RunLevel Highest
For a more integrated solution within your MVC application, Hangfire is excellent despite being a third-party library:
// Install-Package Hangfire
// In Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddHangfire(config => config.UseSqlServerStorage("YourConnectionString"));
}
// Schedule the daily task
RecurringJob.AddOrUpdate("ad-sync", () =>
new BackgroundTaskController().Run(), Cron.Daily);
For modern ASP.NET Core applications, implement a background service:
public class AdSyncService : BackgroundService
{
private readonly HttpClient _httpClient;
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
await _httpClient.GetAsync("http://myapp/BackgroundTask/Run");
await Task.Delay(TimeSpan.FromDays(1), stoppingToken);
}
}
}
When calling internal endpoints:
- Add authentication to your endpoint
- Consider using app-specific credentials
- Validate request origin if possible
Implement proper logging to track execution:
// In your controller
public IActionResult Run()
{
_logger.LogInformation("AD sync started at {Time}", DateTime.UtcNow);
try {
// Your sync logic
}
catch (Exception ex) {
_logger.LogError(ex, "AD sync failed");
}
}
If you're using Azure, WebJobs provide excellent scheduling:
// In a console app
static void Main()
{
var host = new JobHost();
host.Call(typeof(Program).GetMethod("SyncAd"));
}
[NoAutomaticTrigger]
public static void SyncAd(TextWriter log)
{
// Your sync code
}
When building enterprise applications, we often need to run scheduled background processes. In this case, we have an ASP.NET MVC controller endpoint (BackgroundTask/Run
) that performs Active Directory synchronization and updates our database. The challenge is triggering this automatically without manual browser access or external dependencies.
While third-party tools like Hangfire exist, .NET provides built-in mechanisms:
// Option 1: Windows Task Scheduler with PowerShell
$Trigger = New-ScheduledTaskTrigger -Daily -At "3am"
$Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "Invoke-WebRequest -Uri 'http://myapp/BackgroundTask/Run' -UseBasicParsing"
Register-ScheduledTask -TaskName "AD Sync" -Trigger $Trigger -Action $Action
For modern applications, implement IHostedService:
public class AdSyncService : BackgroundService
{
private readonly IHttpClientFactory _clientFactory;
public AdSyncService(IHttpClientFactory clientFactory)
{
_clientFactory = clientFactory;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
var client = _clientFactory.CreateClient();
await client.GetAsync("http://myapp/BackgroundTask/Run");
await Task.Delay(TimeSpan.FromDays(1), stoppingToken);
}
}
}
For SQL Server environments, consider a SQL Agent job that calls the endpoint:
DECLARE @Object INT
DECLARE @ResponseText NVARCHAR(MAX)
EXEC sp_OACreate 'MSXML2.XMLHTTP', @Object OUT
EXEC sp_OAMethod @Object, 'open', NULL, 'GET', 'http://myapp/BackgroundTask/Run', 'false'
EXEC sp_OAMethod @Object, 'send'
EXEC sp_OADestroy @Object
When implementing scheduled tasks:
- Add authentication tokens to your endpoint calls
- Consider firewall rules for internal service calls
- Implement logging to verify execution
- Set up health checks for monitoring
If using Azure, WebJobs provide robust scheduling:
public static void ProcessTimerJob([TimerTrigger("0 0 3 * * *")] TimerInfo timer)
{
var client = new HttpClient();
client.GetAsync("http://myapp/BackgroundTask/Run").Wait();
}