184 lines
6.2 KiB
C#
184 lines
6.2 KiB
C#
using Aitex.Core.Util;
|
||
using Aitex.Core.WCF;
|
||
using MECF.Framework.Common.MultiProcess.ProcessCenter;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Text;
|
||
|
||
namespace MECF.Framework.Common.MultiProcess
|
||
{
|
||
/// <summary>
|
||
/// 用于限制同一区域的机台同时进行工艺的数量;
|
||
/// 客户端首先问询服务端位置是否充足,若条件合适则向服务端进行预定操作;
|
||
///
|
||
/// </summary>
|
||
public class MultiProcessManager : Singleton<MultiProcessManager>
|
||
{
|
||
#region Variables
|
||
|
||
/// <summary>
|
||
/// 加热基数上限
|
||
/// </summary>
|
||
private const int Max_Heart_Num = 4;
|
||
|
||
private const int Max_Heart_Bater_Time = 15;//秒
|
||
|
||
private PeriodicJob _thread;
|
||
|
||
protected readonly R_TRIG _connectionFailed = new();
|
||
|
||
/// <summary>
|
||
/// 腔体列表;预加热与加热状态基数和不能大于4
|
||
/// </summary>
|
||
private readonly List<PMProcessData> _processStateList = [];
|
||
|
||
private static readonly object _lock = new object();
|
||
|
||
#endregion Variables
|
||
|
||
#region Constructors
|
||
|
||
public MultiProcessManager()
|
||
{
|
||
var _thread = new PeriodicJob(15000, OnTimer, $"MultiProcessManager", true);
|
||
}
|
||
|
||
#endregion Constructors
|
||
|
||
#region Methods
|
||
|
||
public void Initialize(bool enableService)
|
||
{
|
||
MULTIPROCESS._multiprocessmanager = this;
|
||
if (enableService)
|
||
{
|
||
Singleton<WcfServiceManager>.Instance.Initialize(new Type[1] { typeof(MultiProcessService) });
|
||
}
|
||
}
|
||
|
||
private bool OnTimer()
|
||
{
|
||
foreach (var item in _processStateList)
|
||
{
|
||
if (IsClientTimeOut(item.HeartBeatTime))
|
||
item.IsOnline = false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
private bool IsClientTimeOut(DateTime heartBeatTime)
|
||
{
|
||
//timeA 表示需要计算
|
||
DateTime timeB = DateTime.Now; //获取当前时间
|
||
TimeSpan ts = timeB - heartBeatTime; //计算时间差
|
||
return ts.TotalSeconds <= Max_Heart_Bater_Time ? false : true;
|
||
}
|
||
|
||
public List<string> QueryAllProcessInformation()
|
||
{
|
||
return PMProcessStateManager.GetProcessInformation(_processStateList);
|
||
}
|
||
|
||
public string QueryMyProcessInformation(string sicMachineName, string pmName)
|
||
{
|
||
return PMProcessStateManager.QueryMyProcessInformation(_processStateList, sicMachineName, pmName);
|
||
}
|
||
public List<PMProcessData> QueryAllProcessData()
|
||
{
|
||
List<PMProcessData> processDataList = new List<PMProcessData>();
|
||
foreach (var item in _processStateList)
|
||
{
|
||
processDataList.Add((PMProcessData)item.Clone());
|
||
}
|
||
return processDataList;
|
||
}
|
||
|
||
public bool CanEnterProcessNow(string clientInformation, string sicMachineName, string pmName, out string result)
|
||
{
|
||
lock (_lock)
|
||
{
|
||
var info = QueryMyProcessInformation(sicMachineName,pmName);
|
||
if (string.IsNullOrEmpty(info))
|
||
{
|
||
result = $"不存在{sicMachineName}.{pmName}";
|
||
return false;
|
||
}
|
||
else if (info != "1")
|
||
{
|
||
result = $"{sicMachineName}.{pmName}当前状态不为ProcessIdle";
|
||
return false;
|
||
}
|
||
|
||
int heartBase = 1 + GetAllHeatBaseNum(out string infor);
|
||
if (heartBase <= Max_Heart_Num)
|
||
{
|
||
result = "OK";
|
||
UpdateChamberEnterState(clientInformation, sicMachineName, pmName, "2");
|
||
return true;
|
||
}
|
||
result = $"加热基数超上限:{Max_Heart_Num} " + infor;
|
||
return false;
|
||
}
|
||
}
|
||
|
||
public bool CanEnterProcessIdleNow(string clientInformation, string sicMachineName, string pmName, out string result)
|
||
{
|
||
lock (_lock)
|
||
{
|
||
int heartBase = 1 + GetAllHeatBaseNum(out string infor);//添加初始基数2
|
||
if (heartBase <= Max_Heart_Num)
|
||
{
|
||
result = "OK";
|
||
UpdateChamberEnterState(clientInformation, sicMachineName, pmName, "1");
|
||
return true;
|
||
}
|
||
result = $"加热基数超上限:{Max_Heart_Num} " + infor;
|
||
return false;
|
||
}
|
||
}
|
||
|
||
public bool UpdateChamberState(string clientInformation, string sicMachineName, string pmName, string state)
|
||
{
|
||
lock (_lock)
|
||
{
|
||
PMProcessData pmProcessData = new()
|
||
{
|
||
SicMachineName = sicMachineName,
|
||
PmName = pmName,
|
||
PmState = state,
|
||
SicMachineID = clientInformation
|
||
};
|
||
return PMProcessStateManager.ProcessStateChangeUpdate(pmProcessData, _processStateList);
|
||
}
|
||
}
|
||
|
||
public bool UpdateChamberEnterState(string clientInformation, string sicMachineName, string pmName, string enterstate)
|
||
{
|
||
lock (_lock)
|
||
{
|
||
PMProcessData pmProcessData = new()
|
||
{
|
||
SicMachineName = sicMachineName,
|
||
PmName = pmName,
|
||
EnterState = enterstate,
|
||
SicMachineID = clientInformation
|
||
};
|
||
return PMProcessStateManager.ProcessEnterStateChangeUpdate(pmProcessData, _processStateList);
|
||
}
|
||
}
|
||
private int GetAllHeatBaseNum(out string infor)
|
||
{
|
||
int heatBase = 0;
|
||
StringBuilder sb = new StringBuilder();
|
||
foreach (var pmProcessData in _processStateList)
|
||
{
|
||
heatBase += PMProcessStateManager.GetHeatBaseNum(pmProcessData);
|
||
sb.Append($"{pmProcessData.SicMachineID} => {pmProcessData.ProcessState} ;");
|
||
}
|
||
infor = sb.ToString();
|
||
return heatBase;
|
||
}
|
||
|
||
#endregion Methods
|
||
}
|
||
} |