Files
huabe-sitondao/SLC1-N/Form_Alarm.cs
2025-11-14 16:12:32 +08:00

255 lines
8.0 KiB
C#

using HslCommunication.Core.IMessage;
using Sunny.UI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SLC1_N
{
public partial class Form_Alarm : Form // 警报弹窗
{
public Form_Alarm()
{
InitializeComponent();
}
private void Form_Alarm_Load(object sender, EventArgs e)
{
}
// 设置报警消息的方法
public void SetAlarmMessage(string message)
{
lb_alarmmsg.Text = message;
}
private void bt_OK_Click(object sender, EventArgs e)
{
this.Close();
}
}
public static class AlarmManager
{
private static Form_Alarm Form_Alarm;
private static readonly Queue<string> m_alarmQueue = new Queue<string>();
public static string nowAlarmMessage; // 记录当前显示的是哪个报警
private static readonly object lockObject = new object();
public static bool isShow = false; // 跟踪弹窗是否正在显示
// 更新报警
public static void UpdateAlarm(string address, bool isshow)
{
lock (lockObject) // 添加锁确保线程安全
{
string message = GetAlarmItem(address);
if (message == null) return;
if (isshow)
{
// 有报警,加入队列(警报不在队列中且不是当前显示的)
if (!m_alarmQueue.Contains(message) && message != nowAlarmMessage)
{
m_alarmQueue.Enqueue(message);
}
// 如果弹窗没显示,就显示
if (!isShow)
{
ShowNextAlarm();
}
}
else
{
if (message == nowAlarmMessage) // 如果是当前显示的报警,关闭弹窗
{
CloseFormAlarm();
}
// 从队列移除对应的报警
if (m_alarmQueue.Contains(message))
{
var newQueue = new Queue<string>(m_alarmQueue.Where(m => m != message));
m_alarmQueue.Clear();
foreach (var msg in newQueue)
{
m_alarmQueue.Enqueue(msg);
}
}
}
}
}
// 显示下一个警报
private static void ShowNextAlarm()
{
lock (lockObject)
{
if (m_alarmQueue.Count > 0 && !isShow)
{
nowAlarmMessage = m_alarmQueue.Dequeue();
if (string.IsNullOrEmpty(nowAlarmMessage))
return;
isShow = true;
// 使用UI线程显示弹窗
if (Application.OpenForms.Count > 0)
{
var mainForm = Application.OpenForms[0];
if (mainForm.InvokeRequired)
{
mainForm.BeginInvoke(new Action(() => ShowAlarmDialog()));
}
else
{
ShowAlarmDialog();
}
}
}
else
{
nowAlarmMessage = null;
}
}
}
// 显示警报对话框
private static void ShowAlarmDialog()
{
try
{
if (Form_Alarm == null || Form_Alarm.IsDisposed)
{
Form_Alarm = new Form_Alarm();
Form_Alarm.FormClosed += (s, e) =>
{
lock (lockObject)
{
isShow = false;
nowAlarmMessage = null;
// 短暂延迟后显示下一个报警,避免竞争条件
Task.Delay(100).ContinueWith(t =>
{
ShowNextAlarm();
}, TaskScheduler.FromCurrentSynchronizationContext());
}
};
}
Form_Alarm.SetAlarmMessage(nowAlarmMessage);
Form_Alarm.StartPosition = FormStartPosition.CenterScreen;
Form_Alarm.TopMost = true; // 确保弹窗在最前面
Form_Alarm.ShowDialog(); // 使用show可能会出问题
}
catch (Exception ex)
{
lock (lockObject)
{
isShow = false;
nowAlarmMessage = null;
// 延迟后重试
Task.Delay(100).ContinueWith(t =>
{
ShowNextAlarm();
}, TaskScheduler.FromCurrentSynchronizationContext());
}
}
}
// 关闭警报弹窗
private static void CloseFormAlarm()
{
if (Form_Alarm != null && !Form_Alarm.IsDisposed && Form_Alarm.Visible)
{
try
{
if (Form_Alarm.InvokeRequired)
{
Form_Alarm.BeginInvoke(new Action(() =>
{
if (!Form_Alarm.IsDisposed && Form_Alarm.Visible)
Form_Alarm.Close();
}));
}
else
{
if (!Form_Alarm.IsDisposed && Form_Alarm.Visible)
Form_Alarm.Close();
}
}
catch (Exception ex)
{
Console.WriteLine($"关闭报警对话框异常: {ex.Message}");
lock (lockObject)
{
isShow = false;
nowAlarmMessage = null;
}
}
}
else
{
lock (lockObject)
{
isShow = false;
nowAlarmMessage = null;
ShowNextAlarm();
}
}
}
// 报警项字典
private static readonly Dictionary<string, string> alarmDictionary = new Dictionary<string, string>
{
{"M1032", "CH1 通道异常"},
{"M1033", "CH2 通道异常"},
{"M1034", "CH3 通道异常"},
{"M1035", "CH4 通道异常"},
{"M1100", "CH1 通道异常光栅触发"},
{"M1101", "CH1 通道异常急停触发"},
{"M1102", "CH1 通道复位后才可启动"},
{"M1103", "CH2 通道异常光栅触发"},
{"M1104", "CH2 通道异常急停触发"},
{"M1105", "CH2 通道复位后才可启动"},
{"M1106", "CH3 通道异常光栅触发"},
{"M1107", "CH3 通道异常急停触发"},
{"M1108", "CH3 通道复位后才可启动"},
{"M1109", "CH4 通道异常光栅触发"},
{"M1110", "CH4 通道异常急停触发"},
{"M1111", "CH4 通道复位后才可启动"},
{"M1112", "设备异常-安全门打开"},
{"M1113", "设备异常-总急停按下"}
};
// 获取报警项
private static string GetAlarmItem(string address)
{
if (alarmDictionary.TryGetValue(address, out string message))
{
return message;
}
return null;
}
}
}