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 { /// /// 定时任务 /// added by ly on 20230802 /// public class TimedTaskBackgroundService : BackgroundService { private IEventPublisher _eventPublisher = default!; private readonly IServiceProvider _serviceProvider; private static Dictionary> _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() != null) .ToDictionary(x => x.Name, x => (Func)Delegate.CreateDelegate(typeof(Func), 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().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(); ////生成任务执行 //CancellationTokenSource genTaskCTS = new(); CancellationTokenSource kittingOutAddCts = new(); CancellationTokenSource kittingOutShippedCts = new(); CancellationTokenSource setSortingCts = new(); CancellationTokenSource isMinStorageCts = new(); //var wareHouseService = App.GetRequiredService(); //TimedTask(cts => wareHouseService.GenTaskExecute(cts), genTaskCTS); //齐套出库 var kittingOutService = App.GetRequiredService(); TimedTask(cts => kittingOutService.KittingOutByAdd(cts), kittingOutAddCts, 1); TimedTask(cts => kittingOutService.KittingOutByIsToBeShipped(cts), kittingOutShippedCts, 1); //齐套分拣 var setSortingService = App.GetRequiredService(); TimedTask(cts => setSortingService.PackSortingByAdd(cts), setSortingCts, 1); var transferSignService = App.GetRequiredService(); TimedTask(cts => transferSignService.IsMinStorage(cts), isMinStorageCts, 30, TimeSpanUnit.Minutes); }, stoppingToken); return Task.WhenAll(queueTask, timedTask); } private Task TimedTask(Func 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; } } }