使用自定义后台任务处理程序

parent 50838fdc
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Internal; using Microsoft.AspNetCore.Http.Internal;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Performance.DtoModels; using Performance.DtoModels;
using Performance.EntityModels; using Performance.EntityModels;
...@@ -32,12 +33,19 @@ public class AllotController : Controller ...@@ -32,12 +33,19 @@ public class AllotController : Controller
private ILogger<AllotController> _logger; private ILogger<AllotController> _logger;
private ClaimService _claim; private ClaimService _claim;
private readonly LogManageService logManageService; private readonly LogManageService logManageService;
private IBackgroundTaskQueue _backgroundTaskQueue;
private IServiceScopeFactory _serviceScopeFactory;
public AllotController(AllotService allotService, public AllotController(AllotService allotService,
ResultComputeService resultComputeService, ResultComputeService resultComputeService,
HospitalService hospitalService, ConfigService configService, HospitalService hospitalService,
ILogger<AllotController> logger, IHostingEnvironment evn, ConfigService configService,
ClaimService claim, LogManageService logManageService) ILogger<AllotController> logger,
IHostingEnvironment evn,
IBackgroundTaskQueue backgroundTaskQueue,
IServiceScopeFactory serviceScopeFactory,
ClaimService claim,
LogManageService logManageService)
{ {
_allotService = allotService; _allotService = allotService;
this.resultComputeService = resultComputeService; this.resultComputeService = resultComputeService;
...@@ -47,6 +55,8 @@ public class AllotController : Controller ...@@ -47,6 +55,8 @@ public class AllotController : Controller
_claim = claim; _claim = claim;
this.logManageService = logManageService; this.logManageService = logManageService;
_configService = configService; _configService = configService;
_backgroundTaskQueue = backgroundTaskQueue;
_serviceScopeFactory = serviceScopeFactory;
} }
/// <summary> /// <summary>
...@@ -182,9 +192,24 @@ public ApiResponse Generate([CustomizeValidator(RuleSet = "Delete"), FromBody] A ...@@ -182,9 +192,24 @@ public ApiResponse Generate([CustomizeValidator(RuleSet = "Delete"), FromBody] A
logManageService.WriteMsg("生成绩效准备中", $"准备生成{allot.Year}-{allot.Month.ToString().PadLeft(2, '0')}月份绩效,请稍等!", 1, allot.ID, "ReceiveMessage", true); logManageService.WriteMsg("生成绩效准备中", $"准备生成{allot.Year}-{allot.Month.ToString().PadLeft(2, '0')}月份绩效,请稍等!", 1, allot.ID, "ReceiveMessage", true);
_allotService.UpdateAllotStates(allot.ID, (int)AllotStates.Wait, EnumHelper.GetDescription(AllotStates.Wait), allot.Generate); _allotService.UpdateAllotStates(allot.ID, (int)AllotStates.Wait, EnumHelper.GetDescription(AllotStates.Wait), allot.Generate);
if (_evn.IsEnvironment("Localhost")) if (_evn.IsEnvironment("Localhost"))
{
_allotService.Generate(allot, email); _allotService.Generate(allot, email);
}
else else
BackgroundJob.Schedule(() => _allotService.Generate(allot, email), TimeSpan.FromSeconds(1)); {
//BackgroundJob.Schedule(() => _allotService.Generate(allot, email), TimeSpan.FromSeconds(1));
_backgroundTaskQueue.QueueBackgroundWorkItem(async token =>
{
using (var scope = _serviceScopeFactory.CreateScope())
{
var scopedServices = scope.ServiceProvider.GetRequiredService<AllotService>();
scopedServices.Generate(allot, email);
await Task.Delay(TimeSpan.FromSeconds(5), token);
}
});
}
logManageService.WriteMsg("等待绩效生成", $"等待绩效生成{allot.Year}-{allot.Month.ToString().PadLeft(2, '0')}月份绩效!", 1, allot.ID, "ReceiveMessage"); logManageService.WriteMsg("等待绩效生成", $"等待绩效生成{allot.Year}-{allot.Month.ToString().PadLeft(2, '0')}月份绩效!", 1, allot.ID, "ReceiveMessage");
//_allotService.Generate(allot, email); //_allotService.Generate(allot, email);
////BackgroundJob.Enqueue(() => _allotService.Generate(allot, email)); ////BackgroundJob.Enqueue(() => _allotService.Generate(allot, email));
......
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace Performance.Api
{
public interface IBackgroundTaskQueue
{
void QueueBackgroundWorkItem(Func<CancellationToken, Task> workItem);
Task<Func<CancellationToken, Task>> DequeueAsync(CancellationToken cancellationToken);
}
public class BackgroundTaskQueue : IBackgroundTaskQueue
{
private readonly ConcurrentQueue<Func<CancellationToken, Task>> _workItems = new ConcurrentQueue<Func<CancellationToken, Task>>();
private readonly SemaphoreSlim _signal = new SemaphoreSlim(0);
public void QueueBackgroundWorkItem(Func<CancellationToken, Task> workItem)
{
if (workItem == null)
{
throw new ArgumentNullException(nameof(workItem));
}
_workItems.Enqueue(workItem);
_signal.Release();
}
public async Task<Func<CancellationToken, Task>> DequeueAsync(CancellationToken cancellationToken)
{
await _signal.WaitAsync(cancellationToken);
_workItems.TryDequeue(out var workItem);
return workItem;
}
}
public class QueuedHostedService : BackgroundService
{
private readonly ILogger<QueuedHostedService> _logger;
public QueuedHostedService(
IBackgroundTaskQueue taskQueue,
ILogger<QueuedHostedService> logger)
{
TaskQueue = taskQueue;
_logger = logger;
}
public IBackgroundTaskQueue TaskQueue { get; }
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation(
$"Queued Hosted Service is running.{Environment.NewLine} {Environment.NewLine}Tap W to add a work item to the background queue.{Environment.NewLine}");
await BackgroundProcessing(stoppingToken);
}
private async Task BackgroundProcessing(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
var workItem =
await TaskQueue.DequeueAsync(stoppingToken);
try
{
await workItem(stoppingToken);
}
catch (Exception ex)
{
_logger.LogError(ex,
"Error occurred executing {WorkItem}.", nameof(workItem));
}
}
}
public override async Task StopAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Queued Hosted Service is stopping.");
await base.StopAsync(stoppingToken);
}
}
}
\ No newline at end of file
...@@ -150,15 +150,18 @@ public void ConfigureServices(IServiceCollection services) ...@@ -150,15 +150,18 @@ public void ConfigureServices(IServiceCollection services)
services.AddMemoryCache(); services.AddMemoryCache();
#region hangfire services.AddHostedService<QueuedHostedService>();
services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
services.AddHangfire(config =>
{ // #region hangfire
config.UseFilter(new AutomaticRetryAttribute { Attempts = 0 }); //
config.UseStorage(new MySqlStorage(connection.Value.HangfireConnectionString)); // services.AddHangfire(config =>
}); // {
// config.UseFilter(new AutomaticRetryAttribute { Attempts = 0 });
#endregion hangfire // config.UseStorage(new MySqlStorage(connection.Value.HangfireConnectionString));
// });
//
// #endregion hangfire
services.AddSignalR(); services.AddSignalR();
services.AddCors(options => services.AddCors(options =>
...@@ -240,12 +243,12 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF ...@@ -240,12 +243,12 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF
#endregion Swagger #endregion Swagger
#region hangfire // #region hangfire
//
app.UseHangfireServer(); // app.UseHangfireServer();
app.UseHangfireDashboard("/hangfire", new DashboardOptions { Authorization = new[] { new HangfireAuthorizationFilter() } }); // app.UseHangfireDashboard("/hangfire", new DashboardOptions { Authorization = new[] { new HangfireAuthorizationFilter() } });
//
#endregion hangfire // #endregion hangfire
app.UseCors("SignalrCore"); app.UseCors("SignalrCore");
app.UseSignalR(routes => routes.MapHub<AllotLogHub>("/performance/allotLogHub")); app.UseSignalR(routes => routes.MapHub<AllotLogHub>("/performance/allotLogHub"));
......
...@@ -3289,19 +3289,9 @@ ...@@ -3289,19 +3289,9 @@
8 归档 9 等待生成 10 绩效结果解析成功 8 归档 9 等待生成 10 绩效结果解析成功
</summary> </summary>
</member> </member>
<member name="P:Performance.DtoModels.SecondPerforResponse.EmployeeName"> <member name="P:Performance.DtoModels.SecondListResponse.ShowFormula">
<summary> <summary>
人员姓名 0 不显示 1 显示
</summary>
</member>
<member name="P:Performance.DtoModels.SecondPerforResponse.JobTitle">
<summary>
职务
</summary>
</member>
<member name="P:Performance.DtoModels.SecondPerforResponse.JobNumber">
<summary>
人员工号
</summary> </summary>
</member> </member>
<member name="P:Performance.DtoModels.SecondPerforResponse.Efficiency"> <member name="P:Performance.DtoModels.SecondPerforResponse.Efficiency">
...@@ -3324,21 +3314,6 @@ ...@@ -3324,21 +3314,6 @@
发放系数 发放系数
</summary> </summary>
</member> </member>
<member name="P:Performance.DtoModels.SecondPerforResponse.ShouldGiveFee">
<summary>
应发管理绩效
</summary>
</member>
<member name="P:Performance.DtoModels.SecondPerforResponse.PerforSumFee">
<summary>
绩效合计
</summary>
</member>
<member name="P:Performance.DtoModels.SecondPerforResponse.ScoreAverageRate">
<summary>
考核对分率
</summary>
</member>
<member name="P:Performance.DtoModels.HeadItem.IsBring"> <member name="P:Performance.DtoModels.HeadItem.IsBring">
<summary> 1 带出历史数据 2不带出 </summary> <summary> 1 带出历史数据 2不带出 </summary>
</member> </member>
......
...@@ -5438,6 +5438,11 @@ ...@@ -5438,6 +5438,11 @@
</summary> </summary>
</member> </member>
<member name="P:Performance.EntityModels.sys_role.IsViewAllUsers">
<summary>
是否查看所有用户 1 启用 2禁用
</summary>
</member>
<member name="T:Performance.EntityModels.sys_role_menu"> <member name="T:Performance.EntityModels.sys_role_menu">
<summary> <summary>
角色菜单关联表 角色菜单关联表
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment