Background Tasks and Scheduled Jobs
Files Referenced in this Document
- MyPluginNameWorker.cs
- MyPluginNameJob.cs
- MyPluginNameArgs.cs
- CMSPluginModule.cs
- CMSPluginEntry.cs
- CMSPluginMyPluginNameExtensions.cs
- appsettings.json
Table of Contents
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
Introduction
This document details the design and implementation of the background asynchronous task processing mechanism in the CMS plugin, covering two main modes: periodic tasks based on BackgroundWorker and scheduled jobs based on Hangfire. It focuses on analyzing how MyPluginNameWorker inherits from AsyncPeriodicBackgroundWorkerBase to implement periodic execution, and how MyPluginNameJob is scheduled and executed through the background job system. It also describes task parameter serialization, registration mechanisms, execution contexts, retry strategies, and monitoring methods, and provides performance tuning suggestions and common issue troubleshooting methods.
Project Structure
This plugin adopts a modular layered architecture. Background task-related code is concentrated in specific directories to ensure clear responsibilities and easy maintenance.
Diagram sources
Section sources
Core Components
This system implements two background task modes: MyPluginNameWorker for periodically executing lightweight tasks, and MyPluginNameJob for executing schedulable, persistent background jobs. The former is registered and runs periodically via IBackgroundWorkerManager, while the latter is registered via AbpBackgroundJobOptions, supporting parameter passing and failure retries.
Section sources
Architecture Overview
The system implements asynchronous processing through the ABP framework's background task mechanism, divided into two systems: periodic workers and persistent jobs. Periodic tasks are driven by AsyncPeriodicBackgroundWorkerBase, triggered by timers; persistent jobs are implemented by BackgroundJob<TArgs>, scheduled and executed by the background job system.
Diagram sources
Detailed Component Analysis
MyPluginNameWorker Analysis
MyPluginNameWorker is a periodic background worker inheriting from AsyncPeriodicBackgroundWorkerBase, responsible for executing timed business logic.
Startup and Configuration
This worker is registered via IBackgroundWorkerManager.AddAsync during the CMSPluginEntry.AfterReadyAsync phase. After startup, it automatically executes according to the configured cycle. The default cycle is 300 seconds (5 minutes), and it runs immediately upon first startup (RunOnStart = true).
Diagram sources
Execution Logic
The DoWorkAsync method is the core execution body, obtaining the service provider via PeriodicBackgroundWorkerContext to access IProjectAccessor for current project information. If the project is valid, business logic (such as OEE calculation annotated in the example) can be executed.
Exception Handling
The framework automatically captures exceptions in DoWorkAsync and logs them, preventing worker termination. If custom exception handling is needed, try-catch blocks can be added within the method.
Section sources
MyPluginNameJob Analysis
MyPluginNameJob is a persistent task based on the ABP background job system, supporting parameter passing, failure retry, and persistent storage.
Task Scheduling
This job is registered in CMSPluginModule.ConfigureServices via AbpBackgroundJobOptions. After registration, it can be enqueued for execution via the IBackgroundJobManager.EnqueueAsync method.
Diagram sources
Parameter Passing Mechanism
MyPluginNameArgs serves as the job parameter class, containing Subject and Body string properties. This object is serialized and stored upon enqueueing, and deserialized and passed to the Execute method during execution, supporting cross-process and cross-machine passing.
Transactions and Data Access
The job internally opens an independent transaction via IUnitOfWorkManager (requiresNew: true) to ensure atomicity of operations. Data access can be performed via IMyEntityNameRepository. If persistent changes are needed, SaveChangesAsync must be explicitly called.
Section sources
Dependency Analysis
Dependencies between system components are clear, achieving loose coupling through dependency injection.
Diagram sources
Performance Considerations
- Periodic Task Frequency:
MyPluginNameWorkerdefaults to executing every 300 seconds. TheTimer.Periodvalue can be adjusted according to business needs to avoid excessive system load from too frequent execution. - Job Concurrency Control:
MyPluginNameJobuses independent transactions to avoid holding connections for long periods. It is recommended to batch process time-consuming operations. - Resource Release: All services are managed by the DI container, no manual resource release needed.
- Log Level: In production environments, it is recommended to use
Informationor higher levels to avoidDebuglogs affecting performance.
Troubleshooting Guide
Task Not Executing
- Check if
MyPluginNameWorkeris successfully registered inCMSPluginEntry.AfterReadyAsync - Confirm if job type is registered via
AddJob<MyPluginNameJob>inCMSPluginModule - Check logs for errors related to
IBackgroundWorkerManagerorIBackgroundJobManager
Task Accumulation
- Check if database connection is normal and job tables (like
BackgroundJobs) are accessible - Confirm Hangfire service (or corresponding background job provider) is running
- Adjust job processing thread count or optimize single job execution time
Deadlock Prevention
- Avoid executing long synchronous operations in
MyPluginNameWorker.DoWorkAsync - Use
requiresNew: trueinMyPluginNameJobto ensure transaction independence and reduce lock contention - Use non-blocking reads (like
ReadUncommitted) for database queries where possible
Parameter Serialization Failure
- Ensure
MyPluginNameArgsand its properties arepublicand haveget/setaccessors - Avoid including delegates, events, or non-serializable fields in parameter classes
Section sources
Conclusion
The system implements a flexible background task processing mechanism through two modes: BackgroundWorker and Hangfire Job. MyPluginNameWorker is suitable for periodic, lightweight tasks, while MyPluginNameJob is suitable for complex jobs requiring persistence, parameterization, and retries. Both are integrated via the ABP framework, possessing good maintainability and extensibility. Reasonably configuring execution frequency, transaction boundaries, and exception handling strategies ensures stable and efficient system operation.