修正InterlockManager中的INTLK动作列表正在加载时,其它线程已经开始遍历该列表,导致异常的问题。
优化InterlockManager中的变量名称。
This commit is contained in:
parent
66ddf8b742
commit
558af89d22
|
@ -18,12 +18,12 @@ public class InterlockDaemonManager : InterlockManagerBase<InterlockDaemonAction
|
|||
public override void Monitor()
|
||||
{
|
||||
// 按Module扫描Interlock Limit
|
||||
foreach (var moduleName in _dicActionsPerModule.Keys.ToList())
|
||||
foreach (var moduleName in _dictINTLKActionsPerModule.Keys.ToList())
|
||||
{
|
||||
Debug.Assert(moduleName != ModuleName.UnDefined,
|
||||
$"Interlock Manager CanSetDo() undesired module name {ModuleName.UnDefined}");
|
||||
|
||||
foreach (var action in _dicActionsPerModule[moduleName].ToList())
|
||||
foreach (var action in _dictINTLKActionsPerModule[moduleName].ToList())
|
||||
action.Monitor();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace Aitex.Core.RT.IOCore.Interlock
|
|||
if (!succeeded)
|
||||
return false;
|
||||
|
||||
_dicModulePostInfo = _dicLimitsPerModule.Keys.ToDictionary(x => x, x => false);
|
||||
_dicModulePostInfo = _dictINTLKActionsPerModule.Keys.ToDictionary(x => x, x => false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ namespace Aitex.Core.RT.IOCore.Interlock
|
|||
public override void Monitor()
|
||||
{
|
||||
// 按Module扫描Interlock Limit
|
||||
foreach (var moduleName in _dicLimitsPerModule.Keys.ToList())
|
||||
foreach (var moduleName in _dictINTLKActionsPerModule.Keys.ToList())
|
||||
{
|
||||
Debug.Assert(moduleName != ModuleName.UnDefined,
|
||||
$"Interlock Manager CanSetDo() undesired module name {ModuleName.UnDefined}");
|
||||
|
@ -86,7 +86,7 @@ namespace Aitex.Core.RT.IOCore.Interlock
|
|||
if (isBypassInterlock)
|
||||
continue;
|
||||
|
||||
foreach (var limit in _dicLimitsPerModule[moduleName].ToList())
|
||||
foreach (var limit in _dictLIMTPerModule[moduleName].ToList())
|
||||
{
|
||||
|
||||
// 如果互锁没被触发
|
||||
|
@ -96,10 +96,10 @@ namespace Aitex.Core.RT.IOCore.Interlock
|
|||
var reverseInfo = new StringBuilder();
|
||||
var module = "System";
|
||||
|
||||
if (!_dicLimitToActionMap.ContainsKey(limit))//新增判断集合中是否包含,防止异常报错
|
||||
if (!_dictLIMT2INTLKActionMap.ContainsKey(limit))//新增判断集合中是否包含,防止异常报错
|
||||
continue;
|
||||
|
||||
var actions = _dicLimitToActionMap[limit].ToList();
|
||||
var actions = _dictLIMT2INTLKActionMap[limit].ToList();
|
||||
foreach (var action in actions)
|
||||
{
|
||||
// 尝试根据Action定义复位该互锁限制条件对应的所有DO的电平
|
||||
|
@ -171,11 +171,15 @@ namespace Aitex.Core.RT.IOCore.Interlock
|
|||
if (isBypassInterlock)
|
||||
return true;
|
||||
|
||||
if (_dictINTLKActionsFileLoader.TryGetValue((doName, onOff), out var ilAction))
|
||||
ilAction.CanDo(out reason);
|
||||
|
||||
/*
|
||||
foreach (var action in _lstActions.Where(action => action.IsSame(doName, onOff)))
|
||||
{
|
||||
return action.CanDo(out reason);
|
||||
}
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.ServiceModel.Configuration;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using Aitex.Core.RT.IOCore.Interlock.DataProvider;
|
||||
|
@ -25,22 +25,22 @@ public abstract class InterlockManagerBase<TAction>
|
|||
|
||||
protected string RootNodeName;
|
||||
|
||||
protected readonly List<TAction> _lstActions;
|
||||
protected readonly ConcurrentDictionary<(string actionName, bool doValue), TAction> _dictINTLKActionsFileLoader;
|
||||
|
||||
/// <summary>
|
||||
/// 每个Limit对应的DoAction集合。
|
||||
/// </summary>
|
||||
protected readonly Dictionary<IInterlockLimit, List<IInterlockAction>> _dicLimitToActionMap;
|
||||
protected readonly Dictionary<IInterlockLimit, List<IInterlockAction>> _dictLIMT2INTLKActionMap;
|
||||
|
||||
/// <summary>
|
||||
/// 每个Module对应的DoAction集合。
|
||||
/// </summary>
|
||||
protected readonly Dictionary<ModuleName, List<TAction>> _dicActionsPerModule;
|
||||
protected readonly Dictionary<ModuleName, List<TAction>> _dictINTLKActionsPerModule;
|
||||
|
||||
/// <summary>
|
||||
/// 每个Module对应的Limit集合。
|
||||
/// </summary>
|
||||
protected readonly Dictionary<ModuleName, List<IInterlockLimit>> _dicLimitsPerModule;
|
||||
protected readonly Dictionary<ModuleName, List<IInterlockLimit>> _dictLIMTPerModule;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -51,10 +51,10 @@ public abstract class InterlockManagerBase<TAction>
|
|||
/// </summary>
|
||||
protected InterlockManagerBase()
|
||||
{
|
||||
_lstActions = new();
|
||||
_dicActionsPerModule = new();
|
||||
_dicLimitToActionMap = new ();
|
||||
_dicLimitsPerModule = new ();
|
||||
_dictINTLKActionsFileLoader = new();
|
||||
_dictINTLKActionsPerModule = new();
|
||||
_dictLIMT2INTLKActionMap = new ();
|
||||
_dictLIMTPerModule = new ();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -172,14 +172,14 @@ public abstract class InterlockManagerBase<TAction>
|
|||
}
|
||||
|
||||
var moduleName = GetModuleFromIo(targetDo.Name);
|
||||
if (!_dicActionsPerModule.ContainsKey(moduleName))
|
||||
_dicActionsPerModule[moduleName] = new List<TAction>();
|
||||
if (!_dictINTLKActionsPerModule.ContainsKey(moduleName))
|
||||
_dictINTLKActionsPerModule[moduleName] = new List<TAction>();
|
||||
|
||||
// 创建InterlockAction对象,首先判断该动作是否已经存在,若存在,则报错
|
||||
var action = (TAction)Activator.CreateInstance(typeof(TAction), moduleName.ToString(),
|
||||
targetDo, doValue, tip, dicTips);
|
||||
|
||||
if (_lstActions.Exists(x => x.IsSame(action.ActionName, doValue)))
|
||||
if (_dictINTLKActionsFileLoader.ContainsKey((action.ActionName, doValue)))
|
||||
{
|
||||
var err = $"Interlock Action {action.ActionName}={doValue} duplicated in {configFile}";
|
||||
LOG.Error(err);
|
||||
|
@ -209,8 +209,16 @@ public abstract class InterlockManagerBase<TAction>
|
|||
}
|
||||
}
|
||||
|
||||
_dicActionsPerModule[moduleName].Add(action);
|
||||
_lstActions.Add(action);
|
||||
_dictINTLKActionsPerModule[moduleName].Add(action);
|
||||
|
||||
if (_dictINTLKActionsFileLoader.ContainsKey((action.ActionName, doValue)))
|
||||
{
|
||||
LOG.Error($"Duplicate interlock action definition: {action.ActionName}, {doValue}");
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!_dictINTLKActionsFileLoader.TryAdd((action.ActionName, doValue), action))
|
||||
LOG.Error($"Unable to add {action} to the ConcurrentDictionary");
|
||||
|
||||
// 如果当前Action设置了忽略翻转,则不要注册Limit到当前Action的映射,避免Limit触发导致Action翻转。
|
||||
if (!ignoreReverse_All)
|
||||
|
@ -220,21 +228,21 @@ public abstract class InterlockManagerBase<TAction>
|
|||
if (!limit.IgnoreReverse)//如果单个limit也忽略反转,不要注册Limit到当前Action的映射,避免Limit触发导致Action翻转。
|
||||
{
|
||||
// 创建以Limit分组的Action字典
|
||||
if (!_dicLimitToActionMap.ContainsKey(limit))
|
||||
_dicLimitToActionMap[limit] = new List<IInterlockAction>();
|
||||
if (!_dictLIMT2INTLKActionMap.ContainsKey(limit))
|
||||
_dictLIMT2INTLKActionMap[limit] = new List<IInterlockAction>();
|
||||
|
||||
_dicLimitToActionMap[limit].Add(action);
|
||||
_dictLIMT2INTLKActionMap[limit].Add(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Debug.Assert(!_dicActionsPerModule.ContainsKey(ModuleName.UnDefined),
|
||||
$"InterlockManager {nameof(_dicActionsPerModule)} contains key {ModuleName.UnDefined}");
|
||||
Debug.Assert(!_dictINTLKActionsPerModule.ContainsKey(ModuleName.UnDefined),
|
||||
$"InterlockManager {nameof(_dictINTLKActionsPerModule)} contains key {ModuleName.UnDefined}");
|
||||
|
||||
Debug.Assert(!_dicLimitsPerModule.ContainsKey(ModuleName.UnDefined),
|
||||
$"InterlockManager {nameof(_dicLimitsPerModule)} contains key {ModuleName.UnDefined}");
|
||||
Debug.Assert(!_dictLIMTPerModule.ContainsKey(ModuleName.UnDefined),
|
||||
$"InterlockManager {nameof(_dictLIMTPerModule)} contains key {ModuleName.UnDefined}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -362,11 +370,11 @@ public abstract class InterlockManagerBase<TAction>
|
|||
return null;
|
||||
}
|
||||
|
||||
// 从_dicLimitsPerModule字典中查找当前创建的Limit是否已经存在;
|
||||
// 从_dictLIMTPerModule字典中查找当前创建的Limit是否已经存在;
|
||||
// 如果存在,直接返回已存在的Limit实例;
|
||||
// 否则,将当前创建的Limit放到字典中,然后返回实例;
|
||||
var moduleName = GetModuleFromIo(limit.Name);
|
||||
if (_dicLimitsPerModule.TryGetValue(moduleName, out var list))
|
||||
if (_dictLIMTPerModule.TryGetValue(moduleName, out var list))
|
||||
{
|
||||
var existLimit = list.FirstOrDefault(x => x.UniqueId == limit.UniqueId);
|
||||
if(existLimit != null)
|
||||
|
@ -377,7 +385,7 @@ public abstract class InterlockManagerBase<TAction>
|
|||
else
|
||||
{
|
||||
// 在字典中创建Module,并将Limit实例放入字典
|
||||
_dicLimitsPerModule[moduleName] = new List<IInterlockLimit>(new[] { limit });
|
||||
_dictLIMTPerModule[moduleName] = new List<IInterlockLimit>(new[] { limit });
|
||||
}
|
||||
|
||||
return limit;
|
||||
|
|
Loading…
Reference in New Issue