fix: 报警分析错误设置循环

This commit is contained in:
Diego
2025-07-02 14:26:25 +08:00
parent 83736647e7
commit 1b2be585af
9 changed files with 100 additions and 55 deletions

View File

@@ -4,10 +4,20 @@
/// <summary>表示可以更改其到期时间和时间段的计时器。</summary>
public interface ITimer : IDisposable
{
/// <summary>更改计时器的启动时间和方法调用之间的时间间隔,使用 TimeSpan 值度量时间间隔。</summary>
/// <summary>更改计时器的启动时间和方法调用之间的时间间隔。</summary>
/// <param name="dueTime">一个 TimeSpan表示在调用构造 ITimer 时指定的回调方法之前的延迟时间量。 指定 InfiniteTimeSpan 可防止重新启动计时器。 指定 Zero 可立即重新启动计时器。</param>
/// <param name="period">构造 Timer 时指定的回调方法调用之间的时间间隔。 指定 InfiniteTimeSpan 可以禁用定期终止。</param>
/// <returns></returns>
Boolean Change(TimeSpan dueTime, TimeSpan period);
public Boolean Change(TimeSpan dueTime, TimeSpan period);
}
#endif
#endif
/// <summary>表示可以更改其到期时间和时间段的计时器。</summary>
public interface ITimerx : IDisposable
{
/// <summary>更改计时器的启动时间和方法调用之间的时间间隔。</summary>
/// <param name="dueTime">一个 TimeSpan表示在调用构造 ITimer 时指定的回调方法之前的延迟时间量。 指定 InfiniteTimeSpan 可防止重新启动计时器。 指定 Zero 可立即重新启动计时器。</param>
/// <param name="period">构造 Timer 时指定的回调方法调用之间的时间间隔。 指定 InfiniteTimeSpan 可以禁用定期终止。</param>
/// <returns></returns>
public Boolean Change(int dueTime, int period);
}

View File

@@ -17,7 +17,7 @@ namespace ThingsGateway.NewLife.Threading;
///
/// TimerX必须维持对象否则Scheduler也没有维持对象时大家很容易一起被GC回收。
/// </remarks>
public class TimerX : ITimer, IDisposable
public class TimerX : ITimer, ITimerx, IDisposable
{
#region
/// <summary>编号</summary>
@@ -382,25 +382,32 @@ public class TimerX : ITimer, IDisposable
return period;
}
}
/// <summary>更改计时器的启动时间和方法调用之间的时间间隔,使用 TimeSpan 值度量时间间隔。</summary>
/// <summary>更改计时器的启动时间和方法调用之间的时间间隔。</summary>
/// <param name="dueTime">一个 TimeSpan表示在调用构造 ITimer 时指定的回调方法之前的延迟时间量。 指定 InfiniteTimeSpan 可防止重新启动计时器。 指定 Zero 可立即重新启动计时器。</param>
/// <param name="period">构造 Timer 时指定的回调方法调用之间的时间间隔。 指定 InfiniteTimeSpan 可以禁用定期终止。</param>
/// <returns></returns>
public Boolean Change(TimeSpan dueTime, TimeSpan period)
{
return Change(dueTime.Milliseconds, period.Milliseconds);
}
/// <summary>更改计时器的启动时间和方法调用之间的时间间隔。</summary>
/// <param name="dueTime">一个 TimeSpan表示在调用构造 ITimer 时指定的回调方法之前的延迟时间量。 指定 InfiniteTimeSpan 可防止重新启动计时器。 指定 Zero 可立即重新启动计时器。</param>
/// <param name="period">构造 Timer 时指定的回调方法调用之间的时间间隔。 指定 InfiniteTimeSpan 可以禁用定期终止。</param>
/// <returns></returns>
public Boolean Change(int dueTime, int period)
{
if (Absolutely) return false;
if (Crons?.Length > 0) return false;
if (period.TotalMilliseconds <= 0)
if (period <= 0)
{
Dispose();
return true;
}
Period = (Int32)period.TotalMilliseconds;
Period = period;
if (dueTime.TotalMilliseconds >= 0) SetNext((Int32)dueTime.TotalMilliseconds);
if (dueTime >= 0) SetNext(dueTime);
return true;
}

View File

@@ -1,8 +1,8 @@
<Project>
<PropertyGroup>
<PluginVersion>10.9.10</PluginVersion>
<ProPluginVersion>10.9.10</ProPluginVersion>
<PluginVersion>10.9.11</PluginVersion>
<ProPluginVersion>10.9.11</ProPluginVersion>
<AuthenticationVersion>2.9.5</AuthenticationVersion>
<SourceGeneratorVersion>10.9.5</SourceGeneratorVersion>
<NET8Version>8.0.17</NET8Version>

View File

@@ -17,6 +17,7 @@ public class CronScheduledTask : DisposeBase, IScheduledTask
private ILog LogMessage;
private volatile int _isRunning = 0;
private volatile int _pendingTriggers = 0;
public Int32 Period => _timer?.Period ?? 0;
public CronScheduledTask(string interval, Func<object?, CancellationToken, Task> taskFunc, object? state, ILog log, CancellationToken token)
{
@@ -143,7 +144,14 @@ public class CronScheduledTask : DisposeBase, IScheduledTask
if (!Check())
_timer?.SetNext(interval);
}
public bool Change(int dueTime, int period)
{
// 延迟触发下一次
if (!Check())
return _timer?.Change(dueTime, period) == true;
return false;
}
public void Stop()
{
_timer?.SafeDispose();

View File

@@ -2,10 +2,11 @@
{
public interface IScheduledTask
{
bool Change(int dueTime, int period);
void SetNext(int interval);
void Start();
void Stop();
public Int32 Period { get; }
}

View File

@@ -16,6 +16,7 @@ public class ScheduledAsyncTask : DisposeBase, IScheduledTask, IScheduledIntInte
private ILog LogMessage;
private volatile int _isRunning = 0;
private volatile int _pendingTriggers = 0;
public Int32 Period => _timer?.Period??0;
public ScheduledAsyncTask(int interval, Func<object?, CancellationToken, Task> taskFunc, object? state, ILog log, CancellationToken token)
{
@@ -86,7 +87,14 @@ public class ScheduledAsyncTask : DisposeBase, IScheduledTask, IScheduledIntInte
_timer?.SetNext(interval);
}
public bool Change(int dueTime, int period)
{
// 延迟触发下一次
if (!Check())
return _timer?.Change(dueTime, period) == true;
return false;
}
public void Stop()
{
_timer?.SafeDispose();

View File

@@ -16,6 +16,7 @@ public class ScheduledSyncTask : DisposeBase, IScheduledTask, IScheduledIntInter
private ILog LogMessage;
private volatile int _isRunning = 0;
private volatile int _pendingTriggers = 0;
public Int32 Period => _timer?.Period ?? 0;
public ScheduledSyncTask(int interval, Action<object?, CancellationToken> taskFunc, object? state, ILog log, CancellationToken token)
{
@@ -89,6 +90,14 @@ public class ScheduledSyncTask : DisposeBase, IScheduledTask, IScheduledIntInter
if (!Check())
_timer?.SetNext(interval);
}
public bool Change(int dueTime, int period)
{
// 延迟触发下一次
if (!Check())
return _timer?.Change(dueTime, period) == true;
return false;
}
public void Stop()
{
_timer?.SafeDispose();

View File

@@ -11,6 +11,9 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Threading;
using ThingsGateway.Gateway.Application.Extensions;
using ThingsGateway.NewLife.Extension;
@@ -398,65 +401,64 @@ internal sealed class AlarmHostedService : BackgroundService, IAlarmHostedServic
/// <param name="cancellation">取消任务的 CancellationToken</param>
private void DoWork(object? state, CancellationToken cancellation)
{
while (!cancellation.IsCancellationRequested)
try
{
if (!GlobalData.StartBusinessChannelEnable)
return;
try
//Stopwatch stopwatch = Stopwatch.StartNew();
// 遍历设备变量列表
if (!GlobalData.AlarmEnableIdVariables.IsEmpty)
{
var list = GlobalData.AlarmEnableIdVariables.Select(a => a.Value).ToArray();
list.ParallelForEach((item, state, index) =>
{
if (!GlobalData.StartBusinessChannelEnable)
return;
//Stopwatch stopwatch = Stopwatch.StartNew();
// 遍历设备变量列表
if (!GlobalData.AlarmEnableIdVariables.IsEmpty)
{
var list = GlobalData.AlarmEnableIdVariables.Select(a => a.Value).ToArray();
list.ParallelForEach((item, state, index) =>
{
{
// 如果取消请求已经被触发,则结束任务
if (cancellation.IsCancellationRequested)
return;
// 如果取消请求已经被触发,则结束任务
if (cancellation.IsCancellationRequested)
return;
// 如果该变量的报警功能未启用,则跳过该变量
if (!item.AlarmEnable)
return;
// 如果该变量的报警功能未启用,则跳过该变量
if (!item.AlarmEnable)
return;
// 如果该变量离线,则跳过该变量
if (!item.IsOnline)
return;
// 如果该变量离线,则跳过该变量
if (!item.IsOnline)
return;
// 对该变量进行报警分析
AlarmAnalysis(item);
// 对该变量进行报警分析
AlarmAnalysis(item);
}
});
}
else
{
scheduledTask.SetNext(5000); // 如果没有启用报警的变量则设置下次执行时间为5秒后
}
});
}
else
{
//if (scheduledTask.Period != 5000)
// scheduledTask.Change(0, 5000); // 如果没有启用报警的变量则设置下次执行时间为5秒后
scheduledTask.SetNext(5000); // 如果没有启用报警的变量则设置下次执行时间为5秒后
}
//stopwatch.Stop();
//_logger.LogInformation("报警分析耗时:" + stopwatch.ElapsedMilliseconds + "ms");
}
catch (OperationCanceledException)
{
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Alarm analysis fail");
}
//stopwatch.Stop();
//_logger.LogInformation("报警分析耗时:" + stopwatch.ElapsedMilliseconds + "ms");
}
catch (OperationCanceledException)
{
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Alarm analysis fail");
}
}
private IScheduledTask scheduledTask;
private ScheduledSyncTask scheduledTask;
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation(AppResource.RealAlarmTaskStart);
scheduledTask = ScheduledTaskHelper.GetTask("10", DoWork, null, null, stoppingToken);
scheduledTask = new ScheduledSyncTask(10, DoWork, null, null, stoppingToken);
scheduledTask.Start();
return Task.CompletedTask;
}

View File

@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>10.9.10</Version>
<Version>10.9.11</Version>
</PropertyGroup>
<ItemGroup>