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

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>
List<AlarmData> listOld = new List<AlarmData>();
List<AlarmData> listNew = new List<AlarmData>();
List<AlarmStatus> listAlarmStatus = null;
//List<AlarmStatus> listAlarmStatus = null;
string alarmStartDate = "";
int AlarmCount = 0;
string strAllAlarm = "";
bool isRead = false;
private readonly object _alarmLock = new object();
private void ShowAlarmEven_Run(string strGuidAlarm)
{
if (CommonMethods.IsRun && CommonMethods.plcDevice.IsConnected)
{
//StringBuilder sb = new StringBuilder();
listNew.Clear();
string Date = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
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)
{
@@ -1595,6 +1602,8 @@ namespace JinYuan.ControlCenters
if (alarmLog == null)
{
listOld.Add(r);
newAlarmData.Add(r.Clone() as AlarmData);
//上传报警
if (CommonMethods.sysConfig.MesModeSwitching)
{
@@ -1614,9 +1623,6 @@ namespace JinYuan.ControlCenters
CommonMethods.SlideAlarmText = strAllAlarm.Substring(0, strAllAlarm.Length - 1);
}
//移除已经消除的报警信息
var saveAlarmData = new List<AlarmData>();
var listOldAlarm = new List<AlarmData>();
listOldAlarm.AddRange(listOld);
if (listOldAlarm.Count > 0)
{
@@ -1626,55 +1632,57 @@ namespace JinYuan.ControlCenters
if (alarmLog == null)
{
item.EndTime = Date;
saveAlarmData.Add(item);
saveAlarmData.Add(item.Clone() as AlarmData);
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 = "";
//写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;
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},";
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)
{
//上传设备报警状态
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<AlarmStatus> listSafeEqptStatus = null;
private void ShowSafeEqptEven_Run()
@@ -1742,7 +1750,7 @@ namespace JinYuan.ControlCenters
/// <summary>
/// 报警保存
/// </summary>
private void SaveAlarmCount(List<AlarmData> alarmDatas)
private void SaveAlarmCount(List<AlarmData> alarmDatas, List<AlarmData> newAlarmDataList)
{
bool ISAdd = false;
var recordToUpdate = new AlarmCountEntry();
@@ -1783,7 +1791,7 @@ namespace JinYuan.ControlCenters
}
else
{
foreach (var m in listNew)
foreach (var m in newAlarmDataList)
{
AlarmCountEntry alarm = new AlarmCountEntry();
alarm.PLCAdress = m.PLCAdress;
+17 -1
View File
@@ -1,11 +1,12 @@
using CsvHelper.Configuration.Attributes;
using System;
namespace JinYuan.Models
{
/// <summary>
/// 工位报警数据
/// </summary>
public class AlarmData
public class AlarmData : ICloneable
{
/// <summary>
/// 报警唯一标识符
@@ -56,6 +57,21 @@ namespace JinYuan.Models
/// 更新状态
/// </summary>
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