diff --git a/Directory.Packages.props b/Directory.Packages.props
index 805da8ba7d..40fb9c08ef 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -183,10 +183,10 @@
-
-
-
-
+
+
+
+
diff --git a/docs/en/framework/infrastructure/background-jobs/tickerq.md b/docs/en/framework/infrastructure/background-jobs/tickerq.md
index de7b3631f2..81dd021607 100644
--- a/docs/en/framework/infrastructure/background-jobs/tickerq.md
+++ b/docs/en/framework/infrastructure/background-jobs/tickerq.md
@@ -95,13 +95,13 @@ public class CleanupJobs
public override Task OnPreApplicationInitializationAsync(ApplicationInitializationContext context)
{
var abpTickerQFunctionProvider = context.ServiceProvider.GetRequiredService();
- abpTickerQFunctionProvider.Functions.TryAdd(nameof(CleanupJobs), (string.Empty, TickerTaskPriority.Normal, new TickerFunctionDelegate(async (cancellationToken, serviceProvider, tickerFunctionContext) =>
+ abpTickerQFunctionProvider.AddFunction(nameof(CleanupJobs), async (cancellationToken, serviceProvider, tickerFunctionContext) =>
{
var service = new CleanupJobs(); // Or get it from the serviceProvider
var request = await TickerRequestProvider.GetRequestAsync(tickerFunctionContext, cancellationToken);
var genericContext = new TickerFunctionContext(tickerFunctionContext, request);
await service.CleanupLogsAsync(genericContext, cancellationToken);
- })));
+ }, TickerTaskPriority.Normal);
abpTickerQFunctionProvider.RequestTypes.TryAdd(nameof(CleanupJobs), (typeof(string).FullName, typeof(string)));
return Task.CompletedTask;
}
diff --git a/docs/en/framework/infrastructure/background-workers/tickerq.md b/docs/en/framework/infrastructure/background-workers/tickerq.md
index d4ddde3cd9..4547b85b85 100644
--- a/docs/en/framework/infrastructure/background-workers/tickerq.md
+++ b/docs/en/framework/infrastructure/background-workers/tickerq.md
@@ -83,13 +83,13 @@ public class CleanupJobs
public override Task OnPreApplicationInitializationAsync(ApplicationInitializationContext context)
{
var abpTickerQFunctionProvider = context.ServiceProvider.GetRequiredService();
- abpTickerQFunctionProvider.Functions.TryAdd(nameof(CleanupJobs), (string.Empty, TickerTaskPriority.Normal, new TickerFunctionDelegate(async (cancellationToken, serviceProvider, tickerFunctionContext) =>
+ abpTickerQFunctionProvider.AddFunction(nameof(CleanupJobs), async (cancellationToken, serviceProvider, tickerFunctionContext) =>
{
var service = new CleanupJobs(); // Or get it from the serviceProvider
var request = await TickerRequestProvider.GetRequestAsync(tickerFunctionContext, cancellationToken);
var genericContext = new TickerFunctionContext(tickerFunctionContext, request);
await service.CleanupLogsAsync(genericContext, cancellationToken);
- })));
+ }, TickerTaskPriority.Normal);
abpTickerQFunctionProvider.RequestTypes.TryAdd(nameof(CleanupJobs), (typeof(string).FullName, typeof(string)));
return Task.CompletedTask;
}
@@ -112,11 +112,11 @@ await cronTickerManager.AddAsync(new CronTickerEntity
You can specify a cron expression instead of using `ICronTickerManager` to add a worker:
```csharp
-abpTickerQFunctionProvider.Functions.TryAdd(nameof(CleanupJobs), (string.Empty, TickerTaskPriority.Normal, new TickerFunctionDelegate(async (cancellationToken, serviceProvider, tickerFunctionContext) =>
+abpTickerQFunctionProvider.AddFunction(nameof(CleanupJobs), async (cancellationToken, serviceProvider, tickerFunctionContext) =>
{
var service = new CleanupJobs();
var request = await TickerRequestProvider.GetRequestAsync(tickerFunctionContext, cancellationToken);
var genericContext = new TickerFunctionContext(tickerFunctionContext, request);
await service.CleanupLogsAsync(genericContext, cancellationToken);
-})));
+}, TickerTaskPriority.Normal);
```
diff --git a/docs/en/package-version-changes.md b/docs/en/package-version-changes.md
index 8e1d492f29..67fce824d8 100644
--- a/docs/en/package-version-changes.md
+++ b/docs/en/package-version-changes.md
@@ -8,6 +8,10 @@
| Microsoft.IdentityModel.Protocols.OpenIdConnect | 8.14.0 | 8.16.0 | #25068 |
| Microsoft.IdentityModel.Tokens | 8.14.0 | 8.16.0 | #25068 |
| System.IdentityModel.Tokens.Jwt | 8.14.0 | 8.16.0 | #25068 |
+| TickerQ | 10.1.1 | 10.2.0 | #25091 |
+| TickerQ.Dashboard | 10.1.1 | 10.2.0 | #25091 |
+| TickerQ.EntityFrameworkCore | 10.1.1 | 10.2.0 | #25091 |
+| TickerQ.Utilities | 10.1.1 | 10.2.0 | #25091 |
## 10.3.0-preview
diff --git a/framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpBackgroundJobsTickerQModule.cs b/framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpBackgroundJobsTickerQModule.cs
index 3d93fc68a1..157f0cc050 100644
--- a/framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpBackgroundJobsTickerQModule.cs
+++ b/framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpBackgroundJobsTickerQModule.cs
@@ -23,26 +23,14 @@ public class AbpBackgroundJobsTickerQModule : AbpModule
{
var abpBackgroundJobOptions = context.ServiceProvider.GetRequiredService>();
var abpBackgroundJobsTickerQOptions = context.ServiceProvider.GetRequiredService>();
- var tickerFunctionDelegates = new Dictionary();
- var requestTypes = new Dictionary();
+ var abpTickerQFunctionProvider = context.ServiceProvider.GetRequiredService();
foreach (var jobConfiguration in abpBackgroundJobOptions.Value.GetJobs())
{
var genericMethod = GetTickerFunctionDelegateMethod.MakeGenericMethod(jobConfiguration.ArgsType);
var tickerFunctionDelegate = (TickerFunctionDelegate)genericMethod.Invoke(null, [jobConfiguration.ArgsType])!;
var config = abpBackgroundJobsTickerQOptions.Value.GetConfigurationOrNull(jobConfiguration.JobType);
- tickerFunctionDelegates.TryAdd(jobConfiguration.JobName, (string.Empty, config?.Priority ?? TickerTaskPriority.Normal, tickerFunctionDelegate));
- requestTypes.TryAdd(jobConfiguration.JobName, (jobConfiguration.ArgsType.FullName, jobConfiguration.ArgsType)!);
- }
-
- var abpTickerQFunctionProvider = context.ServiceProvider.GetRequiredService();
- foreach (var functionDelegate in tickerFunctionDelegates)
- {
- abpTickerQFunctionProvider.Functions.TryAdd(functionDelegate.Key, functionDelegate.Value);
- }
-
- foreach (var requestType in requestTypes)
- {
- abpTickerQFunctionProvider.RequestTypes.TryAdd(requestType.Key, requestType.Value);
+ abpTickerQFunctionProvider.AddFunction(jobConfiguration.JobName, tickerFunctionDelegate, config?.Priority ?? TickerTaskPriority.Normal, config?.MaxConcurrency ?? 0);
+ abpTickerQFunctionProvider.RequestTypes.TryAdd(jobConfiguration.JobName, (jobConfiguration.ArgsType.FullName, jobConfiguration.ArgsType)!);
}
}
diff --git a/framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpBackgroundJobsTimeTickerConfiguration.cs b/framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpBackgroundJobsTimeTickerConfiguration.cs
index ecceaeb28a..1f2c6d32ac 100644
--- a/framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpBackgroundJobsTimeTickerConfiguration.cs
+++ b/framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpBackgroundJobsTimeTickerConfiguration.cs
@@ -10,5 +10,7 @@ public class AbpBackgroundJobsTimeTickerConfiguration
public TickerTaskPriority? Priority { get; set; }
+ public int? MaxConcurrency { get; set; }
+
public RunCondition? RunCondition { get; set; }
}
diff --git a/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpBackgroundWorkersCronTickerConfiguration.cs b/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpBackgroundWorkersCronTickerConfiguration.cs
index 0e8ed89a14..662c05a58a 100644
--- a/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpBackgroundWorkersCronTickerConfiguration.cs
+++ b/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpBackgroundWorkersCronTickerConfiguration.cs
@@ -9,4 +9,6 @@ public class AbpBackgroundWorkersCronTickerConfiguration
public int[]? RetryIntervals { get; set; }
public TickerTaskPriority? Priority { get; set; }
+
+ public int? MaxConcurrency { get; set; }
}
diff --git a/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpTickerQBackgroundWorkerManager.cs b/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpTickerQBackgroundWorkerManager.cs
index 922cad294d..cc6c847197 100644
--- a/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpTickerQBackgroundWorkerManager.cs
+++ b/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpTickerQBackgroundWorkerManager.cs
@@ -53,11 +53,11 @@ public class AbpTickerQBackgroundWorkerManager : BackgroundWorkerManager, ISingl
var name = BackgroundWorkerNameAttribute.GetNameOrNull(worker.GetType()) ?? worker.GetType().FullName;
var config = Options.GetConfigurationOrNull(ProxyHelper.GetUnProxiedType(worker));
- AbpTickerQFunctionProvider.Functions.TryAdd(name!, (string.Empty, config?.Priority ?? TickerTaskPriority.LongRunning, async (tickerQCancellationToken, serviceProvider, tickerFunctionContext) =>
+ AbpTickerQFunctionProvider.AddFunction(name!, async (tickerQCancellationToken, serviceProvider, tickerFunctionContext) =>
{
var workerInvoker = new AbpTickerQPeriodicBackgroundWorkerInvoker(worker, serviceProvider);
await workerInvoker.DoWorkAsync(tickerFunctionContext, tickerQCancellationToken);
- }));
+ }, config?.Priority ?? TickerTaskPriority.LongRunning, config?.MaxConcurrency ?? 0);
AbpTickerQBackgroundWorkersProvider.BackgroundWorkers.Add(name!, new AbpTickerQCronBackgroundWorker
{
diff --git a/framework/src/Volo.Abp.TickerQ/Volo/Abp/TickerQ/AbpTickerQFunctionProvider.cs b/framework/src/Volo.Abp.TickerQ/Volo/Abp/TickerQ/AbpTickerQFunctionProvider.cs
index b92888e533..b6b05e7787 100644
--- a/framework/src/Volo.Abp.TickerQ/Volo/Abp/TickerQ/AbpTickerQFunctionProvider.cs
+++ b/framework/src/Volo.Abp.TickerQ/Volo/Abp/TickerQ/AbpTickerQFunctionProvider.cs
@@ -8,13 +8,33 @@ namespace Volo.Abp.TickerQ;
public class AbpTickerQFunctionProvider : ISingletonDependency
{
- public Dictionary Functions { get;}
+ public Dictionary Functions { get; }
- public Dictionary RequestTypes { get; }
+ public Dictionary RequestTypes { get; }
public AbpTickerQFunctionProvider()
{
- Functions = new Dictionary();
+ Functions = new Dictionary();
RequestTypes = new Dictionary();
}
+
+ public void AddFunction(
+ string name,
+ TickerFunctionDelegate function,
+ TickerTaskPriority priority = TickerTaskPriority.Normal,
+ int maxConcurrency = 0)
+ {
+ Check.NotNullOrWhiteSpace(name, nameof(name));
+ Check.NotNull(function, nameof(function));
+
+ if (maxConcurrency < 0)
+ {
+ throw new ArgumentException("maxConcurrency must be greater than or equal to 0.", nameof(maxConcurrency));
+ }
+
+ if (!Functions.TryAdd(name, (string.Empty, priority, function, maxConcurrency)))
+ {
+ throw new AbpException($"A function with the name '{name}' is already registered.");
+ }
+ }
}
diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.TickerQ/DemoAppTickerQModule.cs b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.TickerQ/DemoAppTickerQModule.cs
index de3ef3c05d..29027a2a75 100644
--- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.TickerQ/DemoAppTickerQModule.cs
+++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.TickerQ/DemoAppTickerQModule.cs
@@ -77,13 +77,13 @@ public class DemoAppTickerQModule : AbpModule
public override Task OnPreApplicationInitializationAsync(ApplicationInitializationContext context)
{
var abpTickerQFunctionProvider = context.ServiceProvider.GetRequiredService();
- abpTickerQFunctionProvider.Functions.TryAdd(nameof(CleanupJobs), (string.Empty, TickerTaskPriority.Normal, new TickerFunctionDelegate(async (cancellationToken, serviceProvider, tickerFunctionContext) =>
+ abpTickerQFunctionProvider.AddFunction(nameof(CleanupJobs), async (cancellationToken, serviceProvider, tickerFunctionContext) =>
{
var service = new CleanupJobs();
var request = await TickerRequestProvider.GetRequestAsync(tickerFunctionContext, cancellationToken);
var genericContext = new TickerFunctionContext(tickerFunctionContext, request);
await service.CleanupLogsAsync(genericContext, cancellationToken);
- })));
+ }, TickerTaskPriority.Normal);
abpTickerQFunctionProvider.RequestTypes.TryAdd(nameof(CleanupJobs), (typeof(string).FullName, typeof(string)));
return Task.CompletedTask;
}