After understanding the fundamentals of Worker Services, let’s explore a practical implementation: a File Watcher Service. This real-world example demonstrates how to apply the concepts we’ve learned to create a robust, production-ready service.
The Challenge
Imagine you need to monitor a directory for new files, perhaps for processing financial transactions or handling automated data imports. You need a service that:
-
Runs continuously
-
Monitors a specific directory
-
Processes new files as they arrive
-
Maintains security and stability
-
Restarts automatically if it fails
The Solution
Let’s create a File Watcher Service that fulfills these requirements. We’ll build upon our Worker Service knowledge and add file system monitoring capabilities.
Step 1: Basic Structure
First, let’s set up our Worker class with file watching capabilities:
public class Worker : BackgroundService
{
private readonly ILogger _logger;
private FileSystemWatcher? _watcher;
private readonly string _watchPath;
private readonly string _fileFilter;
public Worker(ILogger logger, IConfiguration configuration)
{
_logger = logger;
// Get watch path from configuration
_watchPath = configuration.GetValue("WatchSettings:FolderPath")
?? throw new ArgumentNullException("WatchSettings:FolderPath must be set");
_fileFilter = configuration.GetValue("WatchSettings:FileFilter") ?? "*.txt";
}
}
Step 2: Configuration
In appsettings.json, we define our watching parameters:
{
"WatchSettings": {
"FolderPath": "C:\\WatchFolder",
"FileFilter": "*.txt"
}
}
Step 3: Implementing the File Watcher
Now, let’s implement the file watching logic:
public override Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Worker starting at: {time}", DateTimeOffset.Now);
// Ensure directory exists
if (!Directory.Exists(_watchPath))
{
Directory.CreateDirectory(_watchPath);
_logger.LogInformation("Created watch directory: {path}", _watchPath);
}
// Initialize FileSystemWatcher
_watcher = new FileSystemWatcher
{
Path = _watchPath,
Filter = _fileFilter,
NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite,
EnableRaisingEvents = true
};
// Hook up events
_watcher.Created += OnFileCreated;
_watcher.Error += OnError;
return base.StartAsync(cancellationToken);
}
Step 4: File Processing Logic
Here’s how we handle new files:
private void OnFileCreated(object sender, FileSystemEventArgs e)
{
try
{
_logger.LogInformation("New file detected: {file}", e.Name);
// Wait briefly to ensure file is completely written
Thread.Sleep(100);
// Process the file
ProcessFile(e.FullPath);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error processing file: {file}", e.Name);
}
}
Step 5: Service Installation
To install as a Windows Service:
# Create the service
sc.exe create "TSVAutomation" binpath= "C:\path\to\service.exe" start= auto
# Configure automatic restart
sc.exe failure "TSVAutomation" reset= 86400 actions= restart/60000/restart/60000/restart/60000
Applying Best Practices
Our implementation incorporates several best practices:
- Configuration Management
-
External configuration in appsettings.json
-
Environment-specific settings support
-
Fail-fast when required settings are missing
- Error Handling
-
Graceful handling of file system errors
-
Logging of all important events
-
Proper exception management
- Resource Management
-
Proper disposal of FileSystemWatcher
-
Clean shutdown handling
-
Memory-conscious file processing
- Reliability
-
Automatic service restart
-
File lock prevention
-
Robust error recovery
Real-World Considerations
When implementing this service in production, consider:
- Security
-
Proper file access permissions
-
Secure processing of sensitive data
-
Audit logging for file operations
- Performance
-
Batch processing for multiple files
-
Resource throttling
-
Monitoring file processing times
- Maintenance
-
Log rotation
-
Performance monitoring
-
Health checks
Connecting the Dots
This implementation demonstrates key Worker Service concepts:
-
Background processing
-
Resource management
-
Error handling
-
Configuration
-
Logging
-
Service lifetime management
The File Watcher Service shows how Worker Services can solve real-world problems by:
-
Providing continuous monitoring
-
Handling system events
-
Processing data reliably
-
Managing resources efficiently
Next Steps
To enhance this service, consider:
-
Adding file archiving
-
Implementing retry logic
-
Adding email notifications
-
Creating a monitoring dashboard
-
Implementing health checks
Conclusion
By building this File Watcher Service, we’ve seen how Worker Service concepts translate into practical solutions. This implementation provides a foundation that you can build upon for your specific needs, whether it’s processing financial data, handling system automation, or managing file-based workflows.
Remember: The key to a successful Worker Service is balancing functionality with reliability, security, and maintainability.
Have questions about implementing your own Worker Service? Check our previous guide on Worker Service fundamentals!
Have a .NET modernization project?
Free 30-minute scoping call — no pitch, just a direct conversation about your migration.
Get in touch