197 lines
8.1 KiB
C#
197 lines
8.1 KiB
C#
using System.Collections.Concurrent;
|
|
using JNPF;
|
|
using JNPF.Common.Security;
|
|
using JNPF.EventBus;
|
|
using JNPF.EventHandler;
|
|
using JNPF.Systems.Entitys.System;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Tnb.Common.Extension;
|
|
using Tnb.Common.Utils;
|
|
using Tnb.WarehouseMgr.Entities.Configs;
|
|
using Tnb.WarehouseMgr.Entities.Enums;
|
|
using Tnb.WarehouseMgr.Entities.Exceptions;
|
|
|
|
namespace Tnb.WarehouseMgr
|
|
{
|
|
/// <summary>
|
|
/// 定时任务
|
|
/// added by ly on 20230802
|
|
/// </summary>
|
|
public class TimedTaskBackgroundService : BackgroundService
|
|
{
|
|
public bool IsStarted { get; set; }
|
|
private IEventPublisher _eventPublisher = default!;
|
|
private readonly ElevatorControlConfiguration _elevatorControlConfiguration = App.Configuration.Build<ElevatorControlConfiguration>();
|
|
private readonly IServiceProvider _serviceProvider;
|
|
//private static Dictionary<string, Func<CancellationToken?, Task>> _timedFuncMap = new(StringComparer.OrdinalIgnoreCase);
|
|
public TimedTaskBackgroundService(IServiceProvider serviceProvider)
|
|
{
|
|
_serviceProvider = serviceProvider;
|
|
}
|
|
|
|
protected override Task ExecuteAsync(CancellationToken stoppingToken)
|
|
{
|
|
IsStarted = true;
|
|
|
|
Task timedTask = Task.Run(() =>
|
|
{
|
|
_eventPublisher = App.GetRequiredService<IEventPublisher>();
|
|
|
|
//电梯Agv心跳检测
|
|
_ = TimedTask(async token =>
|
|
{
|
|
Dictionary<string, string> parameter = new()
|
|
{
|
|
["DevName"] = _elevatorControlConfiguration.DevName,
|
|
["TagName"] = "AGVKeepalive",
|
|
["Value"] = "123",
|
|
["token"] = _elevatorControlConfiguration.token
|
|
};
|
|
string result = await HttpClientHelper.GetAsync(_elevatorControlConfiguration.WriteTagUrl, pars: parameter);
|
|
await Console.Out.WriteLineAsync($"心跳检测结果:{result}");
|
|
}, stoppingToken, 30, TimeSpanUnit.Seconds);
|
|
////齐套出库
|
|
/*var kittingOutService = App.GetRequiredService<IWmskittingOutService>();
|
|
TimedTask(token => kittingOutService.KittingOutByAdd(token), stoppingToken, 1);
|
|
TimedTask(token => kittingOutService.KittingOutByIsToBeShipped(token), stoppingToken, 1);
|
|
//齐套分拣
|
|
var setSortingService = App.GetRequiredService<IWmsSetSortingService>();
|
|
TimedTask(token => setSortingService.PackSortingByAdd(token), stoppingToken, 2);
|
|
|
|
|
|
//最低库存检查
|
|
var transferSignService = App.GetRequiredService<IWmsPDATransferSignService>();
|
|
TimedTask(token => transferSignService.IsMinStorage(token), stoppingToken, 30, TimeSpanUnit.Minutes);*/
|
|
|
|
}, stoppingToken);
|
|
|
|
return timedTask;
|
|
}
|
|
|
|
|
|
|
|
private Task TimedTask(Func<CancellationToken, Task> action, CancellationToken ct, int interval, TimeSpanUnit timeType = TimeSpanUnit.Seconds)
|
|
{
|
|
CancellationToken token = ct;
|
|
return Task.Factory.StartNew(async () =>
|
|
{
|
|
while (!token.IsCancellationRequested)
|
|
{
|
|
await action(ct).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);
|
|
}
|
|
}, ct, TaskCreationOptions.None, new CustomerTaskScheduler());
|
|
|
|
#region ThreadPool 线程运行会导致线程饥饿
|
|
//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);
|
|
#endregion
|
|
}
|
|
|
|
public override Task StopAsync(CancellationToken cancellationToken)
|
|
{
|
|
|
|
IsStarted = false;
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
}
|
|
/// <summary>
|
|
/// 自定义任务调度器,保证长任务在单独的线程中运行
|
|
/// </summary>
|
|
internal class CustomerTaskScheduler : TaskScheduler
|
|
{
|
|
// 这边的 BlockingCollection 只是举个例子,如果是普通的队列,配合锁也是可以的。
|
|
private readonly BlockingCollection<Task> _tasks = new();
|
|
|
|
public CustomerTaskScheduler()
|
|
{
|
|
Thread thread = new(() =>
|
|
{
|
|
foreach (Task task in _tasks.GetConsumingEnumerable())
|
|
{
|
|
_ = TryExecuteTask(task);
|
|
}
|
|
})
|
|
{
|
|
IsBackground = true
|
|
};
|
|
thread.Start();
|
|
}
|
|
|
|
protected override IEnumerable<Task> GetScheduledTasks()
|
|
{
|
|
return _tasks;
|
|
}
|
|
|
|
protected override void QueueTask(Task task)
|
|
{
|
|
_tasks.Add(task);
|
|
}
|
|
|
|
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
}
|