报警相关代码操作共享集合时有线程安全风险

This commit is contained in:
Administrator
2026-07-08 11:16:16 +08:00
parent a47253ecca
commit 7ddb519051
2 changed files with 103 additions and 79 deletions
+86 -78
View File
@@ -1527,56 +1527,63 @@ namespace JinYuan.ControlCenters
/// <param name="resByte"></param> /// <param name="resByte"></param>
List<AlarmData> listOld = new List<AlarmData>(); List<AlarmData> listOld = new List<AlarmData>();
List<AlarmData> listNew = new List<AlarmData>(); List<AlarmData> listNew = new List<AlarmData>();
List<AlarmStatus> listAlarmStatus = null; //List<AlarmStatus> listAlarmStatus = null;
string alarmStartDate = ""; string alarmStartDate = "";
int AlarmCount = 0; int AlarmCount = 0;
string strAllAlarm = ""; string strAllAlarm = "";
bool isRead = false; bool isRead = false;
private readonly object _alarmLock = new object();
private void ShowAlarmEven_Run(string strGuidAlarm) private void ShowAlarmEven_Run(string strGuidAlarm)
{ {
if (CommonMethods.IsRun && CommonMethods.plcDevice.IsConnected) if (CommonMethods.IsRun && CommonMethods.plcDevice.IsConnected)
{ {
//StringBuilder sb = new StringBuilder();
listNew.Clear();
string Date = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"); string Date = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
JYResult<byte[]> resByte = CommonMethods.PlcLink.ReadValue<JYResult<byte[]>>("D10010", Data_Type.ArrByte, 500); JYResult<byte[]> resByte = CommonMethods.PlcLink.ReadValue<JYResult<byte[]>>("D10010", Data_Type.ArrByte, 500);
if (resByte.IsSuccess && resByte != null)
{
if (resByte == null) { return; }
//如果未配置报警地址信息返回 TODO
if (listAlarmForm == null) { return; }
int startPlcAddr = 10010;//TODO 读取起始地址
//3.公用方法解析byte[]数据 => List<AlarmStatus>
if (resByte == null) { return; } //如果未配置报警地址信息返回
//TODO 切换三菱和欧姆龙
listAlarmStatus = PLCAlarmParseHelper.OmronFinsByte2Status(startPlcAddr, resByte.Content);
//4.判定有不良后,关联AlarmStatus 和AlarmForm
if (listAlarmStatus == null) { return; } //状态信息为空返回
//如果有报警,获取报警信息
if (listAlarmStatus.Any(p => p.Status))
{
//关联表单数据和报警记录,获取报警信息
listNew = listAlarmStatus
.Where(s => s.Status)
.Join(listAlarmForm
, s => s.PLCAdress
, f => f.PLCAdress
, (s, f) => new AlarmData()
{
AlarmGuid = strGuidAlarm,
PLCAdress = s.PLCAdress,
AlarmCode = f.AlarmCode,
AlarmContent = f.AlarmContent == "" ? s.PLCAdress : f.AlarmContent,
AlarmType = "停机报警",
AlarmDesc = f.AlarmContent == "" ? s.PLCAdress : f.AlarmContent,
AlarmState = "1",
StartTime = Date,
EndTime = Date,
Flag = 0
}).ToList();
}
string strAlarm = ""; if (!resByte.IsSuccess || resByte == null || listAlarmForm == null)
{
return;
}
int startPlcAddr = 10010;
var listAlarmStatus = PLCAlarmParseHelper.OmronFinsByte2Status(startPlcAddr, resByte.Content);
if (listAlarmStatus == null || !listAlarmStatus.Any(p => p.Status))
{
return;
}
// 当前新的报警信息
var newAlarmData = new List<AlarmData>();
// 当前已经消除的报警信息
var saveAlarmData = new List<AlarmData>();
var listOldAlarm = new List<AlarmData>();
#region 操作共享列表listNew、listOld时加锁
lock (_alarmLock)
{
listNew.Clear();
//关联表单数据和报警记录,获取报警信息
listNew = listAlarmStatus
.Where(s => s.Status)
.Join(listAlarmForm
, s => s.PLCAdress
, f => f.PLCAdress
, (s, f) => new AlarmData()
{
AlarmGuid = strGuidAlarm,
PLCAdress = s.PLCAdress,
AlarmCode = f.AlarmCode,
AlarmContent = f.AlarmContent == "" ? s.PLCAdress : f.AlarmContent,
AlarmType = "停机报警",
AlarmDesc = f.AlarmContent == "" ? s.PLCAdress : f.AlarmContent,
AlarmState = "1",
StartTime = Date,
EndTime = Date,
Flag = 0
}).ToList();
//添加新的报警信息 //添加新的报警信息
if (listNew.Count > 0) if (listNew.Count > 0)
{ {
@@ -1595,6 +1602,8 @@ namespace JinYuan.ControlCenters
if (alarmLog == null) if (alarmLog == null)
{ {
listOld.Add(r); listOld.Add(r);
newAlarmData.Add(r.Clone() as AlarmData);
//上传报警 //上传报警
if (CommonMethods.sysConfig.MesModeSwitching) if (CommonMethods.sysConfig.MesModeSwitching)
{ {
@@ -1614,9 +1623,6 @@ namespace JinYuan.ControlCenters
CommonMethods.SlideAlarmText = strAllAlarm.Substring(0, strAllAlarm.Length - 1); CommonMethods.SlideAlarmText = strAllAlarm.Substring(0, strAllAlarm.Length - 1);
} }
//移除已经消除的报警信息
var saveAlarmData = new List<AlarmData>();
var listOldAlarm = new List<AlarmData>();
listOldAlarm.AddRange(listOld); listOldAlarm.AddRange(listOld);
if (listOldAlarm.Count > 0) if (listOldAlarm.Count > 0)
{ {
@@ -1626,55 +1632,57 @@ namespace JinYuan.ControlCenters
if (alarmLog == null) if (alarmLog == null)
{ {
item.EndTime = Date; item.EndTime = Date;
saveAlarmData.Add(item); saveAlarmData.Add(item.Clone() as AlarmData);
listOld.Remove(item); listOld.Remove(item);
} }
} }
} }
}
#endregion
if (saveAlarmData.Count > 0) if (saveAlarmData.Count > 0)
{
string strALLAlarm = "";
//写csv文件
var nowDate = DateTime.Now;
string basePath = $@"{CommonMethods.strAlarmLogspath}\{DateTime.Now.Year}\{DateTime.Now.Month}";
string fileName = $@"{nowDate.Day}.csv";
string title = "GUID,报警地址,故障代码,报警内容,开始时间,结束时间,是否停机";
string alarmContent = string.Empty;
List<FaultCodeList> faultCodeLists = new List<FaultCodeList>();
foreach (var m in saveAlarmData)
{ {
string strALLAlarm = ""; FaultCodeList item = new FaultCodeList();
//写csv文件 item.faultCode = m.AlarmCode;
var nowDate = DateTime.Now; faultCodeLists.Add(item);
string basePath = $@"{CommonMethods.strAlarmLogspath}\{DateTime.Now.Year}\{DateTime.Now.Month}"; alarmContent += $"{m.AlarmGuid},{m.PLCAdress},{m.AlarmCode},{m.AlarmContent},{m.StartTime},{m.EndTime},{m.AlarmType}\n";
string fileName = $@"{nowDate.Day}.csv"; strALLAlarm += $"{m.AlarmContent},";
string title = "GUID,报警地址,故障代码,报警内容,开始时间,结束时间,是否停机";
string alarmContent = string.Empty;
List<FaultCodeList> faultCodeLists = new List<FaultCodeList>(); //上传报警
foreach (var m in saveAlarmData)
{
FaultCodeList item = new FaultCodeList();
item.faultCode = m.AlarmCode;
faultCodeLists.Add(item);
alarmContent += $"{m.AlarmGuid},{m.PLCAdress},{m.AlarmCode},{m.AlarmContent},{m.StartTime},{m.EndTime},{m.AlarmType}\n";
strALLAlarm += $"{m.AlarmContent},";
//上传报警
if (CommonMethods.sysConfig.MesModeSwitching)
{
//上传报警
MESDataCombin.EquAlarm(m, 0);
}
}
alarmContent = alarmContent.Substring(0, alarmContent.Length - 1);
CSVHelper<AlarmCSVData>.WriterCSV(basePath, fileName, title, alarmContent);
// 上传消除的报警信息
if (CommonMethods.sysConfig.MesModeSwitching) if (CommonMethods.sysConfig.MesModeSwitching)
{ {
//上传设备报警状态 //上传报警
MESDataCombin.EqpStatusParam("Alert", string.IsNullOrEmpty(alarmStartDate) ? Date : alarmStartDate, strGuidAlarm, faultCodeLists); MESDataCombin.EquAlarm(m, 0);
} }
//报警保存
SaveAlarmCount(saveAlarmData);
} }
alarmContent = alarmContent.Substring(0, alarmContent.Length - 1);
CSVHelper<AlarmCSVData>.WriterCSV(basePath, fileName, title, alarmContent);
// 上传消除的报警信息
if (CommonMethods.sysConfig.MesModeSwitching)
{
//上传设备报警状态
MESDataCombin.EqpStatusParam("Alert", string.IsNullOrEmpty(alarmStartDate) ? Date : alarmStartDate, strGuidAlarm, faultCodeLists);
}
//报警保存
SaveAlarmCount(saveAlarmData, newAlarmData);
} }
} }
} }
List<AlarmData> safeEqptStatus = new List<AlarmData>(); List<AlarmData> safeEqptStatus = new List<AlarmData>();
List<AlarmStatus> listSafeEqptStatus = null; List<AlarmStatus> listSafeEqptStatus = null;
private void ShowSafeEqptEven_Run() private void ShowSafeEqptEven_Run()
@@ -1742,7 +1750,7 @@ namespace JinYuan.ControlCenters
/// <summary> /// <summary>
/// 报警保存 /// 报警保存
/// </summary> /// </summary>
private void SaveAlarmCount(List<AlarmData> alarmDatas) private void SaveAlarmCount(List<AlarmData> alarmDatas, List<AlarmData> newAlarmDataList)
{ {
bool ISAdd = false; bool ISAdd = false;
var recordToUpdate = new AlarmCountEntry(); var recordToUpdate = new AlarmCountEntry();
@@ -1783,7 +1791,7 @@ namespace JinYuan.ControlCenters
} }
else else
{ {
foreach (var m in listNew) foreach (var m in newAlarmDataList)
{ {
AlarmCountEntry alarm = new AlarmCountEntry(); AlarmCountEntry alarm = new AlarmCountEntry();
alarm.PLCAdress = m.PLCAdress; alarm.PLCAdress = m.PLCAdress;
+17 -1
View File
@@ -1,11 +1,12 @@
using CsvHelper.Configuration.Attributes; using CsvHelper.Configuration.Attributes;
using System;
namespace JinYuan.Models namespace JinYuan.Models
{ {
/// <summary> /// <summary>
/// 工位报警数据 /// 工位报警数据
/// </summary> /// </summary>
public class AlarmData public class AlarmData : ICloneable
{ {
/// <summary> /// <summary>
/// 报警唯一标识符 /// 报警唯一标识符
@@ -56,6 +57,21 @@ namespace JinYuan.Models
/// 更新状态 /// 更新状态
/// </summary> /// </summary>
public int Flag { get; set; } public int Flag { get; set; }
public object Clone()
{
return new AlarmData() {
AlarmGuid = this.AlarmGuid,
PLCAdress = this.PLCAdress,
AlarmContent = this.AlarmContent,
AlarmCode = this.AlarmCode,
AlarmType = this.AlarmType,
StartTime = this.StartTime,
EndTime = this.EndTime,
AlarmDesc = this.AlarmDesc,
AlarmState = this.AlarmState,
Flag = this.Flag
};
}
} }
public class AlarmCSVData public class AlarmCSVData