Files
tnb.server/WarehouseMgr/Tnb.WarehouseMgr/TimedTaskBackgroundService.cs
FanLian 61287c5162 注释
2023-08-16 14:31:30 +08:00

157 lines
6.8 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Aop.Api.Domain;
using JNPF;
using JNPF.Common.Core.Manager;
using JNPF.Common.Dtos.Message;
using JNPF.Common.Extension;
using JNPF.Common.Security;
using JNPF.EventBus;
using JNPF.EventHandler;
using JNPF.FriendlyException;
using JNPF.Logging;
using JNPF.Message.Interfaces.Message;
using JNPF.Systems.Entitys.System;
using Mapster;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Natasha.CSharp;
using Tnb.Common.Extension;
using Tnb.WarehouseMgr.Entities.Attributes;
using Tnb.WarehouseMgr.Entities.Dto.Inputs;
using Tnb.WarehouseMgr.Entities.Enums;
using Tnb.WarehouseMgr.Entities.Exceptions;
using Tnb.WarehouseMgr.Interfaces;
namespace Tnb.WarehouseMgr
{
/// <summary>
/// 定时任务
/// added by ly on 20230802
/// </summary>
public class TimedTaskBackgroundService : BackgroundService
{
private IEventPublisher _eventPublisher = default!;
private readonly IServiceProvider _serviceProvider;
private static Dictionary<string, Func<CancellationTokenSource?, Task>> _timedFuncMap = new(StringComparer.OrdinalIgnoreCase);
static TimedTaskBackgroundService()
{
Task.Run(() =>
{
_timedFuncMap = App.EffectiveTypes.AsParallel().Where(t => !t.Namespace.IsNullOrWhiteSpace() && t.Namespace.Contains("Tnb.WarehouseMgr")).SelectMany(t => t.GetMethods())
.Where(m => m.GetCustomAttribute<TimedAttribute>() != null)
.ToDictionary(x => x.Name, x =>
(Func<CancellationTokenSource?, Task>)Delegate.CreateDelegate(typeof(Func<CancellationTokenSource?, Task>), App.GetService(x.DeclaringType), x));
});
}
public TimedTaskBackgroundService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
var queueTask = Task.Run(async () =>
{
var channelReader = _serviceProvider.GetRequiredService<ITaskMessageNotify>().Reader;
CancellationTokenSource? cts = new();
while (channelReader != null && await channelReader.WaitToReadAsync())
{
while (channelReader.TryRead(out var message))
{
if (_timedFuncMap.ContainsKey(message.TaskName))
{
await _timedFuncMap[message.TaskName].Invoke(cts);
}
}
}
}, stoppingToken);
var timedTask = Task.Run(() =>
{
_eventPublisher = App.GetRequiredService<IEventPublisher>();
////生成任务执行
//CancellationTokenSource genTaskCTS = new();
CancellationTokenSource kittingOutAddCts = new();
CancellationTokenSource kittingOutShippedCts = new();
CancellationTokenSource setSortingCts = new();
CancellationTokenSource isMinStorageCts = new();
//var wareHouseService = App.GetRequiredService<IWareHouseService>();
//TimedTask(cts => wareHouseService.GenTaskExecute(cts), genTaskCTS);
//齐套出库
var kittingOutService = App.GetRequiredService<IWmskittingOutService>();
TimedTask(cts => kittingOutService.KittingOutByAdd(cts), kittingOutAddCts, 1);
TimedTask(cts => kittingOutService.KittingOutByIsToBeShipped(cts), kittingOutShippedCts, 1);
//齐套分拣
var setSortingService = App.GetRequiredService<IWmsSetSortingService>();
TimedTask(cts => setSortingService.PackSortingByAdd(cts), setSortingCts, 1);
//最低库存检查
var transferSignService = App.GetRequiredService<IWmsPDATransferSignService>();
TimedTask(cts => transferSignService.IsMinStorage(cts), isMinStorageCts, 30, TimeSpanUnit.Minutes);
}, stoppingToken);
return Task.WhenAll(queueTask, timedTask);
}
private Task TimedTask(Func<CancellationTokenSource, Task> action, CancellationTokenSource cts, int interval, TimeSpanUnit timeType = TimeSpanUnit.Seconds)
{
var token = cts.Token;
return Task.Run(async () =>
{
while (!token.IsCancellationRequested)
{
await action(cts).Catch(async ex =>
{
if (ex is TimedTaskException timedTaskEx and not null)
{
await _eventPublisher.PublishAsync(new LogEventSource("Log:CreateExLog", timedTaskEx.options!, new SysLogEntity
{
Id = SnowflakeIdHelper.NextId(),
Category = 4,
UserId = timedTaskEx.UserId,
UserName = timedTaskEx.UserName,
IPAddress = NetHelper.Ip,
RequestURL = timedTaskEx.RequestURL,
RequestMethod = timedTaskEx.RequestMethod,
Json = timedTaskEx + "\n" + timedTaskEx.InnerException?.StackTrace + "\n" + timedTaskEx?.TargetSite?.GetParameters().ToString(),
//PlatForm = string.Format("{0}-{1}", userAgent.OS.ToString(), userAgent.RawValue),
CreatorTime = DateTime.Now
}));
}
});
await TaskDelay(timeType, interval);
}
}, token);
}
private Task TaskDelay(TimeSpanUnit timeType, int interval)
{
Task delayTask = timeType switch
{
TimeSpanUnit.Milliseconds => Task.Delay(TimeSpan.FromMilliseconds(interval)),
TimeSpanUnit.Seconds => Task.Delay(TimeSpan.FromSeconds(interval)),
TimeSpanUnit.Minutes => Task.Delay(TimeSpan.FromMinutes(interval)),
TimeSpanUnit.Hours => Task.Delay(TimeSpan.FromHours(interval)),
TimeSpanUnit.Days => Task.Delay(TimeSpan.FromDays(interval)),
_ => throw new NotImplementedException()
};
return delayTask;
}
}
}