Skip to main content
Version: Next

Background Tasks and Scheduled Jobs

Files Referenced in this Document

Table of Contents​

  1. Introduction
  2. Project Structure
  3. Core Components
  4. Architecture Overview
  5. Detailed Component Analysis
  6. Dependency Analysis
  7. Performance Considerations
  8. Troubleshooting Guide
  9. 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: MyPluginNameWorker defaults to executing every 300 seconds. The Timer.Period value can be adjusted according to business needs to avoid excessive system load from too frequent execution.
  • Job Concurrency Control: MyPluginNameJob uses 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 Information or higher levels to avoid Debug logs affecting performance.

Troubleshooting Guide​

Task Not Executing​

  • Check if MyPluginNameWorker is successfully registered in CMSPluginEntry.AfterReadyAsync
  • Confirm if job type is registered via AddJob<MyPluginNameJob> in CMSPluginModule
  • Check logs for errors related to IBackgroundWorkerManager or IBackgroundJobManager

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: true in MyPluginNameJob to ensure transaction independence and reduce lock contention
  • Use non-blocking reads (like ReadUncommitted) for database queries where possible

Parameter Serialization Failure​

  • Ensure MyPluginNameArgs and its properties are public and have get/set accessors
  • 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.