From Theory to Practice: Building a File Watcher Service
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<Worker> _logger;
private FileSystemWatcher? _watcher;
private readonly string _watchPath;
private readonly string _fileFilter;
public Worker(ILogger<Worker> logger, IConfiguration configuration)
{
_logger = logger;
// Get watch path from configuration
_watchPath = configuration.GetValue<string>("WatchSettings:FolderPath")
?? throw new ArgumentNullException("WatchSettings:FolderPath must be set");
_fileFilter = configuration.GetValue<string>("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!