using Autofac;
|
using Bro.Common.Base;
|
using Bro.Common.Helper;
|
using Bro.Common.Interface;
|
using Bro.Common.Model;
|
using Bro.Common.Model.Interface;
|
using Bro.Common.PubSub;
|
using Bro.Common.UI;
|
using Bro.Device.AuboRobot;
|
using Bro.Device.OmronFins;
|
using Bro.Device.SeerAGV;
|
using Bro.Device.Station.Forms;
|
using HalconDotNet;
|
using Newtonsoft.Json;
|
using Newtonsoft.Json.Linq;
|
using System;
|
using System.Collections.Concurrent;
|
using System.Collections.Generic;
|
using System.Collections.ObjectModel;
|
using System.Collections.Specialized;
|
using System.Configuration;
|
using System.Diagnostics;
|
using System.Drawing;
|
using System.Drawing.Imaging;
|
using System.IO;
|
using System.Linq;
|
using System.Reflection;
|
using System.Runtime.ExceptionServices;
|
using System.Threading;
|
using System.Threading.Tasks;
|
using static Bro.Common.Helper.EnumHelper;
|
|
namespace A032.Process
|
{
|
public partial class ProcessControl : IStationProcess
|
{
|
ContainerBuilder builder = new ContainerBuilder();
|
|
private void AutoFacRegister(bool isBuild = true)
|
{
|
#region AutoFac注册
|
builder.RegisterInstance<ProcessConfig>(StationConfig as ProcessConfig);
|
builder.RegisterInstance<List<IDevice>>(GetDeviceList());
|
builder.RegisterInstance<List<ProcessMethodAttribute>>(CollectProcessMethods());
|
|
if (isBuild)
|
{
|
GlobalVar.Container = builder.Build();
|
}
|
#endregion
|
}
|
|
public IStationConfig StationConfig { get; set; }
|
|
string CONFIG_PATH = "";
|
private string productionCode = "";
|
public string ProductionCode
|
{
|
get => productionCode;
|
set
|
{
|
if (productionCode != value)
|
{
|
productionCode = value;
|
|
string baseDir = "";
|
|
string configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json");
|
if (File.Exists(configPath))
|
{
|
using (StreamReader reader = new StreamReader(configPath, System.Text.Encoding.UTF8))
|
{
|
string dataStr = reader.ReadToEnd();
|
JObject data = JsonConvert.DeserializeObject<JObject>(dataStr);
|
baseDir = data.Value<string>("ConfigPath");
|
}
|
}
|
|
if (string.IsNullOrWhiteSpace(baseDir))
|
{
|
baseDir = AppDomain.CurrentDomain.BaseDirectory;
|
}
|
|
if (!string.IsNullOrWhiteSpace(productionCode) && productionCode != "Default")
|
{
|
CONFIG_PATH = Path.Combine(baseDir, $"Config_{productionCode}.json");
|
}
|
else
|
{
|
CONFIG_PATH = Path.Combine(baseDir, "Config.json");
|
}
|
}
|
}
|
}
|
|
#region Event
|
public Action<string, Bitmap> OnBitmapOutput { get; set; }
|
public Action<string> OnBitmapClear { get; set; }
|
public Action<string, object> OnObjectOutput { get; set; }
|
public Action<string, Exception> OnExceptionOccured { get; set; }
|
public Action<DeviceState> OnProcessStateChanged { get; set; }
|
#endregion
|
|
#region Property & Field
|
private DeviceState processState = DeviceState.DSUninit;
|
public DeviceState ProcessState
|
{
|
get => processState;
|
set
|
{
|
if (processState != value)
|
{
|
processState = value;
|
Task.Run(() =>
|
{
|
OnProcessStateChanged?.Invoke(value);
|
});
|
//OnProcessStateChanged?.BeginInvoke(value, null, null);
|
}
|
}
|
}
|
|
Dictionary<string, OmronFinsDriver> PLCDict = new Dictionary<string, OmronFinsDriver>();
|
Dictionary<string, AuboRobotDriver> RobotDict = new Dictionary<string, AuboRobotDriver>();
|
Dictionary<string, SeerAGVDriver> AGVDict = new Dictionary<string, SeerAGVDriver>();
|
Dictionary<string, CameraBase> CameraDict = new Dictionary<string, CameraBase>();
|
|
private ProcessConfig Config { get => StationConfig as ProcessConfig; }
|
|
string _configBackupStr = "";
|
|
PubSubCenter PubSubCenter = PubSubCenter.GetInstance();
|
#region constance variables
|
//const int OFFLINE_FLAG = -999;
|
//const int IGNORE_FEEDBACK = -999;
|
#endregion
|
#endregion
|
|
public ProcessControl()
|
{
|
InitialStationProcess();
|
}
|
|
public ProcessControl(string productionCode, string configPath = "")
|
{
|
ProductionCode = productionCode;
|
InitialStationProcess(configPath);
|
}
|
|
public virtual void Close()
|
{
|
if (ProcessState == DeviceState.DSClose)
|
return;
|
|
CloseDevice(PLCDict.Values.ToList());
|
CloseDevice(RobotDict.Values.ToList());
|
CloseDevice(AGVDict.Values.ToList());
|
CloseDevice(CameraDict.Values.ToList());
|
|
ProcessState = DeviceState.DSClose;
|
|
LogAsync(DateTime.Now, "Process Closed", "");
|
}
|
|
public virtual void Open()
|
{
|
if (ProcessState == DeviceState.DSOpen)
|
return;
|
|
InitialProcessMethods();
|
|
OpenDevices(RobotDict.Values.ToList());
|
OpenDevices(AGVDict.Values.ToList());
|
|
OpenCameras();
|
PubSubCenter.Subscribe(PubTag.DeviceOperation.ToString(), OnCameraOp);
|
|
OpenDevices(PLCDict.Values.ToList());
|
|
ProcessState = DeviceState.DSOpen;
|
|
QueryRobotIO();
|
|
//Task.Run(() =>
|
//{
|
// //PLCMonitor();
|
//});
|
|
LogAsync(DateTime.Now, "Process Opened", "");
|
}
|
|
private object OnCameraOp(ISubscriber arg1, object arg2, object arg3)
|
{
|
string cameraId = arg2.ToString();
|
|
if (CameraDict.ContainsKey(cameraId))
|
{
|
CameraDict[cameraId].Snapshot();
|
}
|
|
return null;
|
}
|
|
public virtual void OpenCameras()
|
{
|
//Config.CameraConfigs.ForEach(c =>
|
//{
|
// CameraBase camera = CameraHelper.GetCameraInstance(c.DriverType);
|
// camera.InitialConfig = c;
|
|
// OpenCamera(camera);
|
|
// CameraDict[camera.InitialConfig.ID] = camera;
|
//});
|
|
CameraDict.Values.ToList().ForEach(c =>
|
{
|
OpenCamera(c);
|
});
|
}
|
|
protected void OpenCamera(CameraBase camera)
|
{
|
if (camera.InitialConfig?.IsEnabled ?? false)
|
{
|
camera.UpdateShowImage -= CameraUpdateImage;
|
camera.UpdateShowImage += CameraUpdateImage;
|
camera.OnLog = OnDeviceLog;
|
|
camera.StateChange(DeviceState.DSInit);
|
camera.StateChange(DeviceState.DSOpen);
|
|
(camera as Bro.Device.HikCamera.HikCameraDriver).HImageOutput = HikCameraHImageOutput;
|
}
|
}
|
|
private void HikCameraHImageOutput(HImage arg1, string arg2)
|
{
|
}
|
|
private void OpenDevices<T>(List<T> devices) where T : IDevice
|
{
|
devices.ForEach(d =>
|
{
|
if (d.InitialConfig?.IsEnabled ?? false)
|
{
|
d.OnLog = OnDeviceLog;
|
|
d.StateChange(DeviceState.DSInit);
|
d.StateChange(DeviceState.DSOpen);
|
}
|
});
|
}
|
|
private void CloseDevice<T>(List<T> devices) where T : IDevice
|
{
|
devices.ForEach(d =>
|
{
|
if (d.CurrentState != DeviceState.DSClose)
|
{
|
d.StateChange(DeviceState.DSClose);
|
}
|
});
|
}
|
|
public List<ProcessMethodAttribute> CollectProcessMethods()
|
{
|
List<ProcessMethodAttribute> resultList = new List<ProcessMethodAttribute>();
|
var methods = this.GetType().GetMethods().ToList();
|
|
methods.ForEach(m =>
|
{
|
var attr = m.GetCustomAttribute<ProcessMethodAttribute>();
|
if (attr != null)
|
{
|
resultList.Add(attr);
|
}
|
});
|
|
return resultList;
|
}
|
|
public void InitialStationProcess(string configPath = "")
|
{
|
ProcessException.OnExceptionNotice = LogAsync;
|
|
StationConfig = LoadStationConfig(configPath);
|
|
#region 个别配置的特别处理
|
|
#endregion
|
|
_warningRemains.CollectionChanged -= _warningRemains_CollectionChanged;
|
_warningRemains.CollectionChanged += _warningRemains_CollectionChanged;
|
|
InitialPLCs();
|
InitialRobots();
|
InitialAGVs();
|
InitialCameras();
|
|
AutoFacRegister();
|
|
LogAsync(DateTime.Now, "Process Initialized", "");
|
}
|
|
private void InitialCameras()
|
{
|
Config.CameraConfigCollection.ForEach(c =>
|
{
|
CameraBase camera = CameraHelper.GetCameraInstance(c.DriverType);
|
camera.InitialConfig = c;
|
CameraDict[camera.InitialConfig.ID] = camera;
|
});
|
}
|
|
private void InitialPLCs()
|
{
|
Config.PLCConfigCollection.ForEach(c =>
|
{
|
OmronFinsDriver plc = new OmronFinsDriver();
|
plc.InitialConfig = c;
|
PLCDict[plc.InitialConfig.ID] = plc;
|
|
plc.OnMonitorAlarm -= Plc_OnMonitorAlarm;
|
plc.OnMonitorInvoke -= Plc_OnMonitorInvoke;
|
|
plc.OnMonitorAlarm += Plc_OnMonitorAlarm;
|
plc.OnMonitorInvoke += Plc_OnMonitorInvoke;
|
});
|
}
|
|
private void InitialRobots()
|
{
|
Config.RobotConfigCollection.ForEach(c =>
|
{
|
AuboRobotDriver robot = new AuboRobotDriver();
|
robot.InitialConfig = c;
|
RobotDict[robot.InitialConfig.ID] = robot;
|
});
|
}
|
|
private void InitialAGVs()
|
{
|
Config.AGVConfigCollection.ForEach(c =>
|
{
|
SeerAGVDriver agv = new SeerAGVDriver();
|
agv.InitialConfig = c;
|
AGVDict[agv.InitialConfig.ID] = agv;
|
});
|
}
|
|
public void InitialStationProcess()
|
{
|
InitialStationProcess("");
|
}
|
|
private ProcessConfig LoadStationConfig(string configPath = "")
|
{
|
ProcessConfig config = new ProcessConfig();
|
|
if (string.IsNullOrWhiteSpace(configPath))
|
{
|
configPath = CONFIG_PATH;
|
}
|
|
try
|
{
|
if (File.Exists(configPath))
|
{
|
using (StreamReader reader = new StreamReader(configPath, System.Text.Encoding.UTF8))
|
{
|
_configBackupStr = reader.ReadToEnd();
|
config = JsonConvert.DeserializeObject<ProcessConfig>(_configBackupStr, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All });
|
}
|
}
|
|
if (config == null)
|
{
|
config = new ProcessConfig();
|
}
|
}
|
catch (Exception ex)
|
{
|
}
|
|
return config;
|
}
|
|
public void Pause()
|
{
|
}
|
|
public void Resume()
|
{
|
}
|
|
public void SaveStationConfig(IStationConfig config)
|
{
|
AutoFacRegister(false);
|
|
ProcessConfig pConfig = config as ProcessConfig;
|
if (pConfig == null)
|
throw new ProcessException("目前只支持ProcessConfig类型的非空内容保存", null);
|
|
string newConfig = JsonConvert.SerializeObject(pConfig, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto });
|
using (StreamWriter writer = new StreamWriter(CONFIG_PATH, false, System.Text.Encoding.UTF8))
|
{
|
writer.Write(newConfig);
|
writer.Flush();
|
writer.Close();
|
}
|
|
if (_configBackupStr != newConfig)
|
{
|
SaveBackupConfig();
|
}
|
}
|
|
private void SaveBackupConfig()
|
{
|
string backPath = Path.GetDirectoryName(CONFIG_PATH);
|
backPath = Path.Combine(backPath, ProductionCode + "_bk");
|
if (!Directory.Exists(backPath))
|
{
|
Directory.CreateDirectory(backPath);
|
}
|
|
backPath = Path.Combine(backPath, $"Config_{ProductionCode}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.json");
|
|
using (StreamWriter writer = new StreamWriter(backPath, false, System.Text.Encoding.UTF8))
|
{
|
writer.Write(_configBackupStr);
|
writer.Flush();
|
writer.Close();
|
}
|
}
|
|
/// <summary>
|
/// 调用方法的字典集合
|
/// Key:MethodCode,Value:MethodInfo
|
/// </summary>
|
public Dictionary<string, MethodInfo> _processMethodDict = new Dictionary<string, MethodInfo>();
|
|
/// <summary>
|
/// Halcon算法工具字典,在初始化时统一一次性载入
|
/// Key:MethodCode,Value:HalconTool
|
/// </summary>
|
protected Dictionary<string, HDevEngineTool> _halconToolDict = new Dictionary<string, HDevEngineTool>();
|
|
private void InitialProcessMethods()
|
{
|
_processMethodDict = new Dictionary<string, MethodInfo>();
|
var methods = this.GetType().GetMethods().ToList();
|
methods.ForEach(m =>
|
{
|
var attr = m.GetCustomAttribute<ProcessMethodAttribute>();
|
if (attr != null)
|
{
|
_processMethodDict[attr.MethodCode] = m;
|
|
#region 初始化HalconTool
|
//if (attr.DeviceType.EndsWith("Camera"))
|
//{
|
// if (StationConfig.ProcessOpConfigDict.Keys.Contains(attr.MethodCode))
|
// {
|
// var opConfig = StationConfig.ProcessOpConfigDict[attr.MethodCode] as HalconRelatedCameraOprerationConfigBase;
|
|
// if (opConfig != null)
|
// {
|
// if (!string.IsNullOrWhiteSpace(opConfig.AlgorithemPath))
|
// {
|
// string directoryPath = Path.GetDirectoryName(opConfig.AlgorithemPath);
|
// string fileName = Path.GetFileNameWithoutExtension(opConfig.AlgorithemPath);
|
|
// HDevEngineTool tool = new HDevEngineTool(directoryPath);
|
// tool.LoadProcedure(fileName);
|
|
// _halconToolDict[attr.MethodCode] = tool;
|
// }
|
// }
|
// }
|
//}
|
#endregion
|
}
|
});
|
|
#region 初始化HalconTool
|
_halconToolDict = new Dictionary<string, HDevEngineTool>();
|
Config.PLCConfigCollection.SelectMany(plcConfig => plcConfig.MonitorSetCollection).Select(ms => ms.OpConfig).ToList().ForEach(c =>
|
{
|
IHalconToolPath toolPath = c as IHalconToolPath;
|
if (toolPath != null)
|
{
|
toolPath.GetHalconToolPathList().ForEach(path =>
|
{
|
if (!string.IsNullOrWhiteSpace(path))
|
{
|
string directoryPath = Path.GetDirectoryName(path);
|
string fileName = Path.GetFileNameWithoutExtension(path);
|
|
HDevEngineTool tool = new HDevEngineTool(directoryPath);
|
tool.LoadProcedure(fileName);
|
|
_halconToolDict[path] = tool;
|
}
|
});
|
}
|
});
|
#endregion
|
}
|
|
public List<IDevice> GetDeviceList()
|
{
|
List<IDevice> list = new List<IDevice>();
|
|
list.AddRange(PLCDict.Values);
|
list.AddRange(RobotDict.Values);
|
list.AddRange(AGVDict.Values);
|
list.AddRange(CameraDict.Values);
|
|
return list;
|
}
|
|
#region PLC监听
|
|
private void Plc_OnMonitorInvoke(DateTime dt, MonitorSet monitorSet)
|
{
|
IOperationConfig config = monitorSet.OpConfig;
|
string methodCode = monitorSet.MethodCode;
|
object res = null;
|
int reTryTimes = config.ReTryTimes;
|
|
do
|
{
|
try
|
{
|
//有IOperationConfig参数的调用
|
res = _processMethodDict[methodCode].Invoke(this, new object[] { config });
|
reTryTimes = -1;
|
}
|
catch (Exception invokeEX) //流程动作异常失败
|
{
|
Exception ex = invokeEX.InnerException == null ? invokeEX : invokeEX.InnerException;
|
reTryTimes--;
|
|
if (reTryTimes <= 0) //如果没有重试次数了就通知PLC
|
{
|
if (config == null || config.ExceptionValue == 0)
|
{
|
if (!(ex is ProcessException))
|
{
|
//如果是算法异常,返回NG值;否则返回异常值
|
if (ex is HDevEngineException)
|
{
|
res = new ProcessResponse((int)ReturnValue.NGVALUE);
|
}
|
else
|
{
|
res = new ProcessResponse((int)ReturnValue.EXCEPTIONVALUE);
|
}
|
|
var newEx = new ProcessException("函数" + methodCode + "执行异常", ex);
|
}
|
else
|
{
|
if ((ex as ProcessException).OriginalException != null)
|
{
|
res = new ProcessResponse((int)ReturnValue.EXCEPTIONVALUE);
|
}
|
else
|
{
|
res = new ProcessResponse((int)ReturnValue.NGVALUE);
|
}
|
}
|
}
|
else
|
{
|
res = new ProcessResponse(config.ExceptionValue);
|
}
|
|
LogAsync(DateTime.Now, methodCode + "异常信息", ex.GetExceptionMessage());
|
}
|
}
|
|
if (reTryTimes > 0)
|
{
|
LogAsync(DateTime.Now, methodCode + " reTryTimes", reTryTimes.ToString());
|
}
|
} while (reTryTimes > 0);
|
|
#region 设置返回值
|
monitorSet.Response = res as ProcessResponse;
|
|
//测试模式下始终反馈OK信号
|
if (StationConfig.IsDemoMode && monitorSet.Response.ResultValue <= 0)
|
{
|
monitorSet.Response.ResultValue = (int)ReturnValue.OKVALUE;
|
}
|
#endregion
|
|
//sw.Stop();
|
//LogAsync(DateTime.Now, methodCode + " 调用耗时: " + sw.ElapsedMilliseconds.ToString() + "ms", "");
|
//TimeRecordCSV(DateTime.Now, methodCode + "调用", (int)sw.ElapsedMilliseconds);
|
//sw.Start();
|
|
#region 原有PLC写入结果操作,现转到异步调用后回调去执行
|
//ProcessResponse resValues = res as ProcessResponse;
|
|
//if (resValues.ResultValue == (int)PLCReplyValue.IGNORE)
|
//{
|
// return;
|
//}
|
|
//if (monitorSet.ReplyDataAddress != -1 && resValues.DataList.Count > 0)
|
//{
|
// PLC_ITEM item = new PLC_ITEM();
|
// item.OP_TYPE = 2;
|
// item.ITEM_LENGTH = resValues.DataList.Count;
|
// item.ADDRESS = monitorSet.ReplyDataAddress.ToString();
|
// item.ITEM_VALUE = String.Join(",", resValues.DataList);
|
// PLC.WriteItem(item, false);
|
//}
|
|
//if (monitorSet.NoticeAddress != -1)
|
//{
|
// //测试模式下始终反馈OK信号
|
// if (StationConfig.IsDemoMode && resValues.ResultValue <= 0)
|
// {
|
// resValues.ResultValue = (int)ReturnValue.OKVALUE;
|
// }
|
|
// int repeatTime = 5;
|
|
// //LogAsync(DateTime.Now, methodCode + "开始反馈", "");
|
// do
|
// {
|
// try
|
// {
|
// PLC.WriteSingleAddress(set.NoticeAddress, resValues.ResultValue, false);
|
// repeatTime = 0;
|
// }
|
// catch (Exception ex)
|
// {
|
// repeatTime--;
|
|
// if (repeatTime <= 0)
|
// {
|
// new ProcessException("PLC反馈写入异常", ex);
|
// }
|
// }
|
// } while (repeatTime > 0);
|
//}
|
#endregion
|
}
|
|
private void Plc_OnMonitorAlarm(DateTime dt, WarningSet warning, bool isAlarmRaised)
|
{
|
}
|
|
//List<int> _monitorList = new List<int>();
|
//List<MonitorSet> _monitorSetList = new List<MonitorSet>();
|
//List<string> _methodCodeList = new List<string>();
|
|
//ConcurrentDictionary<string, Task> _halconTaskDict = new ConcurrentDictionary<string, Task>();
|
//ConcurrentDictionary<string, AutoResetEvent> _halconHandleDict = new ConcurrentDictionary<string, AutoResetEvent>();
|
|
///// <summary>
|
///// PLC监听
|
///// </summary>
|
//private void PLCMonitor()
|
//{
|
// _monitorSetList = StationConfig.PLCMonitorSet.Values.ToList();
|
// _methodCodeList = StationConfig.PLCMonitorSet.Keys.ToList();
|
|
// while (PLC.CurrentState == DeviceState.DSOpen)
|
// {
|
// try
|
// {
|
// List<int> newMonitorList = PLC.Monitor(PLC.IConfig.EventStartAddress, PLC.IConfig.EventLength);
|
|
// if (newMonitorList == null || newMonitorList.Count == 0)
|
// continue;
|
|
// Stopwatch sw = new Stopwatch();
|
// sw.Start();
|
// if (_monitorList.Count == newMonitorList.Count)
|
// {
|
// var tempNew = new List<int>(newMonitorList);
|
// var tempOld = new List<int>(_monitorList);
|
// //Task.Run(() =>
|
// //{
|
// MonitorCheckAndInvoke(tempNew, tempOld);
|
// //});
|
// }
|
// _monitorList = new List<int>(newMonitorList);
|
// sw.Stop();
|
|
// if (sw.ElapsedMilliseconds > 10)
|
// {
|
// LogAsync(DateTime.Now, $"轮询时间:{sw.ElapsedMilliseconds}", "");
|
// TimeRecordCSV(DateTime.Now, "轮询时间", (int)sw.ElapsedMilliseconds);
|
// }
|
|
// Thread.Sleep(PLC.IConfig.ScanInterval);
|
// }
|
// catch (Exception ex)
|
// {
|
// LogAsync(DateTime.Now, "PLC监听异常", ex.GetExceptionMessage());
|
// }
|
// };
|
//}
|
|
//private void MonitorCheckAndInvoke(List<int> newMonitorList, List<int> monitorList)
|
//{
|
// //await Task.Run(() =>
|
// {
|
// Parallel.For(0, monitorList.Count, (index) =>
|
// //for (int index = 0; index < monitorList.Count; index++)
|
// {
|
// int plcValue = newMonitorList[index];
|
// int plcOldValue = monitorList[index];
|
|
// #region PLC警报信息
|
// //bool warningSignal = (index >= Config.PLCConfig.WarningStartIndex && index < Config.PLCConfig.WarningStartIndex + Config.PLCConfig.WarningLength);
|
|
// // if (warningSignal)
|
// // {
|
// // if (plcValue != plcOldValue)
|
// // {
|
// // int warningIndex = index - Config.PLCConfig.WarningStartIndex;
|
// // for (int i = 0; i < 16; i++)
|
// // {
|
// // var ws = StationConfig.WarningSets.FirstOrDefault(w => w.WaringIndex == (warningIndex * 16) + i);
|
|
// // if (ws != null)
|
// // {
|
// // int newValue = plcValue >> i & 1;
|
// // int oldValue = plcOldValue >> i & 1;
|
|
// // if (newValue != oldValue)
|
// // {
|
// // //CurrentPubSub.Publish(PubTag.PLCWarningUpdate.ToString(), newValue == 1, ws, true);
|
|
// // //仅保存警报信息,不保存提示信息
|
// // if (ws.WarningLvl == 0)
|
// // {
|
// // if (newValue == 1)
|
// // {
|
// // if (!_warningRemains.Contains(ws.WarningCode))
|
// // {
|
// // _warningRemains.Add(ws.WarningCode);
|
// // }
|
// // }
|
// // else
|
// // {
|
// // if (_warningRemains.Contains(ws.WarningCode))
|
// // {
|
// // _warningRemains.Remove(ws.WarningCode);
|
// // }
|
// // }
|
|
// // SaveAlarm(Config.StationCode, ws, newValue);
|
// // }
|
// // }
|
// // }
|
// // }
|
// // }
|
|
// // //continue;
|
// // return;
|
// // }
|
// #endregion
|
|
// if (plcValue != plcOldValue)
|
// {
|
// _monitorSetList.Where(u => u.TriggerIndex == index).ToList().ForEach(monitorSet =>
|
// {
|
// int monitorSetIndex = _monitorSetList.IndexOf(monitorSet);
|
// string methodCode = _methodCodeList[monitorSetIndex];
|
// LogAsync(DateTime.Now, $"索引{monitorSet.TriggerIndex}变动,方法:{methodCode}", $"原先值:{plcOldValue},变化值:{plcValue}");
|
|
// //触发值为-999时,监听地址数据变动即触发函数
|
// if (monitorSet != null && (plcValue == monitorSet.TriggerValue || monitorSet.TriggerValue == -999))
|
// {
|
// List<int> inputData = new List<int>();
|
// if (monitorSet.InputDataIndex != null && monitorSet.InputDataIndex.Count > 0)
|
// {
|
// monitorSet.InputDataIndex.ForEach(p =>
|
// {
|
// inputData.Add(newMonitorList[p]);
|
// });
|
// }
|
|
// LogAsync(DateTime.Now, "PLC触发", methodCode + "触发\r\n触发值:" + plcValue + ";传入值:" + (inputData == null || inputData.Count == 0 ? "NA" : string.Join(",", inputData)));
|
|
// if (_halconToolDict.Keys.Contains(methodCode))
|
// {
|
// if (!_halconTaskDict.Keys.Contains(methodCode))
|
// {
|
// _halconHandleDict[methodCode] = new AutoResetEvent(false);
|
// _halconTaskDict[methodCode] = new Task((obj) =>
|
// {
|
// while (true)
|
// {
|
// _halconHandleDict[methodCode].WaitOne();
|
|
// if (PLC.CurrentState != DeviceState.DSOpen)
|
// continue;
|
|
// object[] objs = obj as object[];
|
// int msIndex = Convert.ToInt32(objs[0]);
|
// MonitorSet set = objs[1] as MonitorSet;
|
// List<int> inputDataIndex = objs[2] as List<int>;
|
// List<int> datas = new List<int>();
|
|
// if (inputDataIndex != null)
|
// {
|
// inputDataIndex.ForEach(p =>
|
// {
|
// datas.Add(newMonitorList[p]);
|
// });
|
// }
|
|
// MethodHandle(msIndex, set, datas, plcValue);
|
// }
|
// }, new object[] { monitorSetIndex, monitorSet, monitorSet.InputDataIndex });
|
|
// _halconTaskDict[methodCode].Start();
|
// }
|
|
// _halconHandleDict[methodCode].Set();
|
// }
|
// else
|
// {
|
// ThreadPool.QueueUserWorkItem(MethodHandle, new object[] { monitorSetIndex, monitorSet, inputData, plcValue });
|
// }
|
// }
|
// });
|
// }
|
// }
|
// );
|
// }
|
// //);
|
//}
|
|
//private void MethodHandle(object obj)
|
//{
|
// object[] objs = obj as object[];
|
// int monitorSetIndex = Convert.ToInt32(objs[0]);
|
// MonitorSet set = objs[1] as MonitorSet;
|
// List<int> inputDataValue = objs[2] as List<int>;
|
// int triggerValue = Convert.ToInt32(objs[3]);
|
|
// MethodHandle(monitorSetIndex, set, inputDataValue, triggerValue);
|
//}
|
|
//private void MethodHandle(int monitorSetIndex, MonitorSet set, List<int> inputDataValue, int triggerValue)
|
//{
|
// //await Task.Run(() =>
|
// //Task.Run(() =>
|
// {
|
// string methodCode = _methodCodeList[monitorSetIndex];
|
// Stopwatch sw = new Stopwatch();
|
// sw.Start();
|
|
// try
|
// {
|
// if (_processMethodDict.Keys.Contains(methodCode))
|
// {
|
// IOperationConfig config = null;
|
// if (StationConfig.ProcessOpConfigDict.Keys.Contains(methodCode))
|
// {
|
// config = StationConfig.ProcessOpConfigDict[methodCode];
|
// }
|
// else
|
// {
|
// config = new OperationConfigBase();
|
// }
|
|
// config.InputPara = inputDataValue;
|
|
// object res = null;
|
// int reTryTimes = config.ReTryTimes;
|
|
// do
|
// {
|
// try
|
// {
|
// //有IOperationConfig参数的调用
|
// res = _processMethodDict[methodCode].Invoke(this, new object[] { config });
|
// reTryTimes = -1;
|
// }
|
// catch (Exception invokeEX) //流程动作异常失败
|
// {
|
// Exception ex = invokeEX.InnerException == null ? invokeEX : invokeEX.InnerException;
|
// reTryTimes--;
|
|
// if (reTryTimes <= 0) //如果没有重试次数了就通知PLC
|
// {
|
// //保存最后一次NG的图片
|
// //SaveNGImage(_processMethodDict[methodCode]);
|
|
// if (config == null || config.ExceptionValue == 0)
|
// {
|
// if (!(ex is ProcessException))
|
// {
|
// //CurrentPubSub.Publish(PubTag.ExceptionUpdate.ToString(), "函数" + methodCode + "执行异常", ex, true);
|
|
// //如果是算法异常,返回NG值;否则返回异常值
|
// if (ex is HDevEngineException)
|
// {
|
// res = new ProcessResponse((int)ReturnValue.NGVALUE);
|
// }
|
// else
|
// {
|
// res = new ProcessResponse((int)ReturnValue.EXCEPTIONVALUE);
|
// }
|
|
// var newEx = new ProcessException("函数" + methodCode + "执行异常", ex);
|
// }
|
// else
|
// {
|
// if ((ex as ProcessException).OriginalException != null)
|
// {
|
// res = new ProcessResponse((int)ReturnValue.EXCEPTIONVALUE);
|
// }
|
// else
|
// {
|
// res = new ProcessResponse((int)ReturnValue.NGVALUE);
|
// }
|
// }
|
// }
|
// else
|
// {
|
// res = new ProcessResponse(config.ExceptionValue);
|
// }
|
|
// LogAsync(DateTime.Now, methodCode + "异常信息", ex.GetExceptionMessage());
|
// }
|
// }
|
|
// if (reTryTimes > 0)
|
// {
|
// LogAsync(DateTime.Now, methodCode + " reTryTimes", reTryTimes.ToString());
|
// }
|
// } while (reTryTimes > 0);
|
|
// sw.Stop();
|
// LogAsync(DateTime.Now, methodCode + " 调用耗时: " + sw.ElapsedMilliseconds.ToString() + "ms", "");
|
// TimeRecordCSV(DateTime.Now, methodCode + "调用", (int)sw.ElapsedMilliseconds);
|
// sw.Start();
|
|
// ProcessResponse resValues = res as ProcessResponse;
|
|
// //if (resValues != null)
|
// //{
|
// if (resValues.ResultValue == (int)PLCReplyValue.IGNORE)
|
// {
|
// return;
|
// }
|
|
// if (set.ReplyDataAddress != -1 && resValues.DataList.Count > 0)
|
// {
|
// //int stepLength = 120;
|
// //int startAdd = set.ReplyDataAddress;
|
|
// //while (resValues.DataList.Count > 0)
|
// //{
|
// // var data = resValues.DataList.Take(stepLength).ToList();
|
|
// // PLC_ITEM item = new PLC_ITEM();
|
// // item.OP_TYPE = 2;
|
// // item.ITEM_LENGTH = data.Count;
|
// // item.ADDRESS = startAdd.ToString();
|
// // item.ITEM_VALUE = String.Join(",", data);
|
// // PLC.WriteItem(item);
|
|
// // if (resValues.DataList.Count > stepLength)
|
// // {
|
// // startAdd += stepLength;
|
// // resValues.DataList = resValues.DataList.Skip(stepLength).ToList();
|
// // }
|
// //}
|
|
// //if (resValues.DataList.Count > 0)
|
// //{
|
// PLC_ITEM item = new PLC_ITEM();
|
// item.OP_TYPE = 2;
|
// item.ITEM_LENGTH = resValues.DataList.Count;
|
// item.ADDRESS = set.ReplyDataAddress.ToString();
|
// item.ITEM_VALUE = String.Join(",", resValues.DataList);
|
// PLC.WriteItem(item, false);
|
// //}
|
// }
|
|
// if (set.NoticeAddress != -1)
|
// {
|
// //测试模式下始终反馈OK信号
|
// if (StationConfig.IsDemoMode && resValues.ResultValue <= 0)
|
// {
|
// resValues.ResultValue = (int)ReturnValue.OKVALUE;
|
// }
|
|
// int repeatTime = 5;
|
|
// //LogAsync(DateTime.Now, methodCode + "开始反馈", "");
|
// do
|
// {
|
// try
|
// {
|
// PLC.WriteSingleAddress(set.NoticeAddress, resValues.ResultValue, false);
|
// repeatTime = 0;
|
// }
|
// catch (Exception ex)
|
// {
|
// repeatTime--;
|
|
// if (repeatTime <= 0)
|
// {
|
// new ProcessException("PLC反馈写入异常", ex);
|
// }
|
// }
|
// } while (repeatTime > 0);
|
// //LogAsync(DateTime.Now, methodCode + "结束反馈", "");
|
// }
|
// //}
|
// }
|
// }
|
// catch (Exception ex)
|
// {
|
// LogAsync(DateTime.Now, _methodCodeList[monitorSetIndex] + "调用异常", ex.GetExceptionMessage());
|
// }
|
// //finally
|
// //{
|
// // //IdleFlag--;
|
// // //_idleTimer.Change(BaseConfig.IdleTimeThreshold * 1000, Timeout.Infinite);
|
|
// //}
|
|
// sw.Stop();
|
// LogAsync(DateTime.Now, methodCode + " Elapsed: " + sw.ElapsedMilliseconds.ToString() + "ms", "");
|
// TimeRecordCSV(DateTime.Now, methodCode + "完成", (int)sw.ElapsedMilliseconds);
|
// }
|
// //);
|
//}
|
|
//private async void CTHandle(OperationCTCollection ct, int plcValue)
|
//{
|
// await Task.Run(() =>
|
// {
|
// if (plcValue == 0)
|
// {
|
// ct.CSVOutput(StationConfig.CSVFilePath);
|
|
// //ct.CTList.ForEach(u =>
|
// foreach (var u in ct.CTList)
|
// {
|
// u.StartTime = null;
|
// u.EndTime = null;
|
// }
|
// //);
|
|
// //CurrentPubSub.Publish(PubTag.CTUpdate.ToString(), ct, null, true);
|
// }
|
// else
|
// {
|
// for (int i = 0; i < ct.CTList.Count; i++)
|
// {
|
// if (plcValue == ct.CTList[i].OpTrigger)
|
// {
|
// DateTime dt = DateTime.Now;
|
|
// if (i < ct.CTList.Count - 1)
|
// {
|
// ct.CTList[i].StartTime = dt;
|
// }
|
|
// if (i > 1)
|
// {
|
// ct.CTList[i - 1].EndTime = dt;
|
// }
|
|
// //CurrentPubSub.Publish(PubTag.CTUpdate.ToString(), ct, null, true);
|
// break;
|
// }
|
// }
|
// }
|
// });
|
//}
|
|
//public virtual ProcessResponse MonitorMethodInvoke(string methodCode, IOperationConfig config)
|
//{
|
// return _processMethodDict[methodCode].Invoke(this, new object[] { config }) as ProcessResponse;
|
// //return null;
|
//}
|
#endregion
|
|
#region 图像处理
|
protected Dictionary<string, Queue<string>> CameraBitmapDict = new Dictionary<string, Queue<string>>();
|
//protected Dictionary<string, Bitmap> CameraBitmapDict = new Dictionary<string, Bitmap>();
|
|
protected HObject CollectHImage(CameraBase camera, IOperationConfig opConfig, string cameraId, string methodCode)
|
{
|
HObject hImage = null;
|
|
if (StationConfig.IsImageOffline)
|
{
|
using (OfflineImageFrm oiF = new OfflineImageFrm())
|
{
|
if (oiF.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
{
|
hImage = oiF.HImg;
|
}
|
else
|
{
|
//MessageBox.Show("未能获取离线图片!");
|
throw new ProcessException("未能获取离线图片!", null);
|
}
|
}
|
}
|
else
|
{
|
Stopwatch sw = new Stopwatch();
|
sw.Start();
|
|
var cameraConifg = opConfig as HalconRelatedCameraOprerationConfigBase;
|
if (cameraConifg.DelayBefore > 0)
|
{
|
Thread.Sleep(cameraConifg.DelayBefore);
|
}
|
|
camera.UploadOperationConfig(opConfig);
|
camera.Snapshot(opConfig, out hImage);
|
|
//SaveTempImage(cameraName, camera.ImageFilePath);
|
//SaveTempImage(camera, cameraId);
|
|
if (cameraConifg.DelayAfter > 0)
|
{
|
Thread.Sleep(cameraConifg.DelayAfter);
|
}
|
|
sw.Stop();
|
LogAsync(DateTime.Now, $"{methodCode}采图耗时:{sw.ElapsedMilliseconds}ms", "");
|
TimeRecordCSV(DateTime.Now, methodCode + "采图", (int)sw.ElapsedMilliseconds);
|
}
|
|
return hImage;
|
}
|
|
//private async void SaveTempImage(string cameraName, string imgFilePath)
|
//{
|
// await Task.Run(() =>
|
// {
|
// //if (!string.IsNullOrWhiteSpace(cameraId))
|
// //{
|
// // //if (CameraBitmapDict.ContainsKey(cameraId) && CameraBitmapDict[cameraId] != null)
|
// // //{
|
// // // CameraBitmapDict[cameraId].Dispose();
|
// // // CameraBitmapDict[cameraId] = null;
|
// // //}
|
// // CameraBitmapDict[cameraId] = imgFilePath;
|
// //}
|
|
// CameraBitmapDict[cameraName] = imgFilePath;
|
// });
|
//}
|
|
private async void SaveTempImage(CameraBase camera, string cameraId)
|
{
|
await Task.Run(() =>
|
{
|
//if (!string.IsNullOrWhiteSpace(cameraId))
|
//{
|
// //if (CameraBitmapDict.ContainsKey(cameraId) && CameraBitmapDict[cameraId] != null)
|
// //{
|
// // CameraBitmapDict[cameraId].Dispose();
|
// // CameraBitmapDict[cameraId] = null;
|
// //}
|
// CameraBitmapDict[cameraId] = imgFilePath;
|
//}
|
|
//camera.ImageGetHandle.WaitOne();
|
//CameraBitmapDict[cameraName] = camera.ShowImage;
|
|
if (string.IsNullOrWhiteSpace(cameraId))
|
return;
|
|
camera.ImageSaveDoneHandle.WaitOne();
|
|
if (!CameraBitmapDict.ContainsKey(cameraId))
|
{
|
CameraBitmapDict.Add(cameraId, new Queue<string>());
|
}
|
CameraBitmapDict[cameraId].Enqueue(camera.ImageFilePath);
|
});
|
}
|
|
protected async void CameraUpdateImage(CameraBase camera, Bitmap image, string imageFilePath)
|
{
|
await Task.Run(() =>
|
{
|
OnBitmapOutput?.Invoke(camera.InitialConfig.ID, image);
|
});
|
}
|
|
//protected async void SaveNGImage(MethodInfo methodInfo)
|
//{
|
// await Task.Run(() =>
|
// {
|
// try
|
// {
|
// if (string.IsNullOrWhiteSpace(Config.NGImageFolderPath))
|
// return;
|
|
// var attr = methodInfo.GetCustomAttribute<CameraInvokeAttribute>();
|
// if (attr == null)
|
// return;
|
|
// SaveCameraImage(attr.CameraName);
|
// }
|
// catch (Exception ex)
|
// {
|
// LogAsync(DateTime.Now, "保存NG图片异常", ex.GetExceptionMessage());
|
// }
|
// });
|
//}
|
|
//protected void SaveCameraImage(string cameraName)
|
//{
|
// try
|
// {
|
// if (CameraBitmapDict.ContainsKey(cameraName))
|
// {
|
// DirectoryInfo dir = new DirectoryInfo(Path.Combine(Config.NGImageFolderPath, DateTime.Now.ToString("yyyyMMdd")));
|
// if (!dir.Exists)
|
// dir.Create();
|
|
// //string imageFilePath = Path.Combine(dir.FullName, DateTime.Now.ToString("HHmmssfff") + ".jpg");
|
|
// //if (CameraBitmapDict[cameraName] != null)
|
// // CameraBitmapDict[cameraName].Save(imageFilePath, ImageFormat.Jpeg);
|
|
// FileInfo file = new FileInfo(CameraBitmapDict[cameraName]);
|
// if (file.Exists)
|
// {
|
// file.CopyTo(Path.Combine(dir.FullName, file.Name));
|
// }
|
// }
|
// }
|
// catch (Exception ex)
|
// {
|
// LogAsync(DateTime.Now, "保存相机图片异常", ex.GetExceptionMessage());
|
// }
|
//}
|
|
//private async void SaveFitImage(CameraBase camera, HalconRelatedCameraOprerationConfigBase config, List<ElementBase> list)
|
//{
|
// await Task.Run(() =>
|
// {
|
// if (!config.IsSaveFitImage)
|
// return;
|
|
// if (string.IsNullOrWhiteSpace(config.FitImagePath))
|
// return;
|
|
// string imageFilePath = "";
|
|
// int repeatTime = 15;
|
// do
|
// {
|
// if (CameraBitmapDict.ContainsKey(camera.InitialConfig.ID) && CameraBitmapDict[camera.InitialConfig.ID].Count > 0)
|
// {
|
// imageFilePath = CameraBitmapDict[camera.InitialConfig.ID].Dequeue();
|
// }
|
|
// if (string.IsNullOrWhiteSpace(imageFilePath) || !File.Exists(imageFilePath))
|
// {
|
// repeatTime--;
|
// Thread.Sleep(50);
|
// }
|
// else
|
// {
|
// repeatTime = 0;
|
// }
|
|
// } while (repeatTime > 0);
|
|
// if (string.IsNullOrWhiteSpace(imageFilePath))
|
// return;
|
|
// var dir = new DirectoryInfo(Path.Combine(config.FitImagePath, DateTime.Now.ToString("yyyyMMdd")));
|
// if (!dir.Exists)
|
// {
|
// dir.Create();
|
// }
|
|
// repeatTime = 10;
|
// do
|
// {
|
// try
|
// {
|
// string fileName = Path.GetFileNameWithoutExtension(imageFilePath);
|
// fileName = Path.Combine(dir.FullName, fileName + ".jpg");
|
// Bitmap image = (Bitmap)Image.FromFile(imageFilePath);
|
|
// SaveFitImage(image, list, fileName);
|
|
// repeatTime = 0;
|
// }
|
// catch (Exception ex)
|
// {
|
// repeatTime--;
|
// LogAsync(DateTime.Now, "保存拟合图片异常1", ex.GetExceptionMessage());
|
// Thread.Sleep(500);
|
// }
|
// } while (repeatTime > 0);
|
// });
|
//}
|
|
//[HandleProcessCorruptedStateExceptions]
|
//private async void SaveFitImage(Bitmap image, List<ElementBase> eleList, string fileName)
|
//{
|
// await Task.Run(() =>
|
// {
|
// if (image == null)
|
// return;
|
|
// Bitmap map = new Bitmap(image.Width, image.Height);
|
// using (Graphics g = Graphics.FromImage(map))
|
// {
|
// int saveRetry = 15;
|
// do
|
// {
|
// try
|
// {
|
// g.DrawImage(image, 0, 0);
|
|
// eleList.ForEach(e =>
|
// {
|
// int repeatTime = 5;
|
// do
|
// {
|
// try
|
// {
|
// e.State = ElementState.Normal;
|
// e.Draw(g);
|
// repeatTime = 0;
|
// }
|
// catch (Exception)
|
// {
|
// repeatTime--;
|
// }
|
// } while (repeatTime > 0);
|
// });
|
|
// map.Save(fileName, ImageFormat.Jpeg);
|
// saveRetry = 0;
|
// }
|
// //catch (System.AccessViolationException ex)
|
// //{
|
// // saveRetry--;
|
// // LogAsync(DateTime.Now, "保存拟合图片异常2", ex.GetExceptionMessage());
|
|
// // Thread.Sleep(100);
|
// //}
|
// catch (Exception ex)
|
// {
|
// saveRetry--;
|
// LogAsync(DateTime.Now, "保存拟合图片异常2", ex.GetExceptionMessage());
|
|
// Thread.Sleep(100);
|
// }
|
// } while (saveRetry > 0);
|
// }
|
|
// map.Dispose();
|
// image.Dispose();
|
// });
|
//}
|
#endregion
|
|
#region 报警和DownTime
|
public ObservableCollection<string> _warningRemains = new ObservableCollection<string>();
|
|
bool warningRemainFlag = false;
|
bool WarningRemainFlag
|
{
|
get
|
{
|
return warningRemainFlag;
|
}
|
set
|
{
|
if (value && !warningRemainFlag)
|
{
|
//CurrentPubSub.Publish(EnumHelper.PubTag.DownTimeNotice.ToString(), true, null, true);
|
//SaveDownTime(DateTime.Now, true);
|
}
|
|
if (!value)
|
{
|
//CurrentPubSub.Publish(EnumHelper.PubTag.DownTimeNotice.ToString(), false, null, true);
|
//SaveDownTime(DateTime.Now, false);
|
}
|
|
warningRemainFlag = value;
|
}
|
}
|
|
private void _warningRemains_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
{
|
//lock (_idleTimeLock)
|
//{
|
// if (_warningRemains.Count == 0)
|
// {
|
// if (!_idleFlag)
|
// {
|
// StartIdleRecordAsync();
|
// }
|
|
// WarningRemainFlag = false;
|
// }
|
// else
|
// {
|
// if (_idleFlag)
|
// {
|
// //_idleFlag = false;
|
// EndIdleRecordAsync();
|
// }
|
|
// WarningRemainFlag = true;
|
// }
|
//}
|
}
|
|
private void SaveAlarm(string stationCode, WarningSet ws, int newValue)
|
{
|
}
|
#endregion
|
|
#region Log
|
static object logObj = new object();
|
public Action<DateTime, string, string> OnLog;
|
public virtual async void LogAsync(DateTime dt, string prefix, string msg)
|
{
|
await Task.Run(() =>
|
{
|
OnLog?.BeginInvoke(dt, prefix, msg, null, null);
|
|
if (!StationConfig.IsLogEnabled)
|
return;
|
|
DirectoryInfo dir = new DirectoryInfo(StationConfig.LogPath);
|
if (!dir.Exists)
|
{
|
dir.Create();
|
}
|
|
string logPath = Path.Combine(StationConfig.LogPath, DateTime.Today.ToString("yyyyMMdd") + ".txt");
|
|
lock (logObj)
|
{
|
using (StreamWriter writer = new StreamWriter(logPath, true, System.Text.Encoding.UTF8))
|
{
|
//writer.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
|
writer.WriteLine(dt.ToString("yyyy-MM-dd HH:mm:ss.fff"));
|
writer.WriteLine(prefix);
|
writer.Write(msg);
|
writer.WriteLine();
|
writer.WriteLine();
|
|
writer.Flush();
|
writer.Close();
|
}
|
}
|
});
|
}
|
|
protected void OnDeviceLog(DateTime dt, IDevice device, string msg)
|
{
|
LogAsync(dt, device.InitialConfig.Name, msg);
|
}
|
|
static object csvLock = new object();
|
private async void TimeRecordCSV(DateTime dt, string desc, int ms)
|
{
|
await Task.Run(() =>
|
{
|
lock (csvLock)
|
{
|
string filePath = Path.Combine(Config.LogPath, $"TimeRecords_{DateTime.Now.ToString("yyyyMMdd")}.csv");
|
bool isFileExisted = File.Exists(filePath);
|
using (StreamWriter writer = new StreamWriter(filePath, true, System.Text.Encoding.UTF8))
|
{
|
if (!isFileExisted)
|
{
|
writer.WriteLine("Time,Prefix,Consumed");
|
}
|
writer.WriteLine($"{dt.ToString("HH:mm:ss.fff")},{desc},{ms}");
|
writer.Flush();
|
writer.Close();
|
}
|
}
|
});
|
}
|
#endregion
|
|
#region 临时数据保存和读取
|
protected static Dictionary<string, object> _tempDataLock = new Dictionary<string, object>();
|
protected string _tempFileDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TempData");
|
|
protected virtual T ReadTempDataFromHistory<T>(T t, string propertyName) where T : class
|
{
|
if (!_tempDataLock.ContainsKey(propertyName))
|
{
|
_tempDataLock[propertyName] = new object();
|
}
|
|
if (t != null)
|
{
|
return t;
|
}
|
else
|
{
|
if (!Directory.Exists(_tempFileDirectory))
|
{
|
Directory.CreateDirectory(_tempFileDirectory);
|
}
|
|
string filePath = Path.Combine(_tempFileDirectory, propertyName);
|
|
if (!File.Exists(filePath))
|
{
|
return null;
|
}
|
|
lock (_tempDataLock[propertyName])
|
{
|
using (StreamReader reader = new StreamReader(filePath, System.Text.Encoding.UTF8))
|
{
|
string content = reader.ReadToEnd();
|
var result = JsonConvert.DeserializeObject<T>(content);
|
return result;
|
}
|
}
|
}
|
}
|
|
protected virtual void SaveTempData<T>(T t, string propertyName, string defaultStr = "")
|
{
|
//await Task.Run(() =>
|
{
|
if (!_tempDataLock.ContainsKey(propertyName))
|
{
|
_tempDataLock[propertyName] = new object();
|
}
|
|
lock (_tempDataLock[propertyName])
|
{
|
try
|
{
|
if (!Directory.Exists(_tempFileDirectory))
|
{
|
Directory.CreateDirectory(_tempFileDirectory);
|
}
|
|
string serialStr = JsonConvert.SerializeObject(t);
|
|
if (!string.IsNullOrWhiteSpace(defaultStr))
|
{
|
if (t == null)
|
{
|
serialStr = defaultStr;
|
}
|
}
|
else
|
{
|
if (t == null)
|
return;
|
}
|
|
string filePath = Path.Combine(_tempFileDirectory, propertyName);
|
|
using (StreamWriter writer = new StreamWriter(filePath, false, System.Text.Encoding.UTF8))
|
{
|
writer.Write(serialStr);
|
writer.Flush();
|
writer.Close();
|
}
|
}
|
catch (Exception)
|
{
|
}
|
}
|
}
|
//);
|
}
|
#endregion
|
}
|
|
public enum ReturnValue
|
{
|
OKVALUE = 1,
|
NGVALUE = -1,
|
EXCEPTIONVALUE = -2,
|
LEVEL3EXCEPTION = -3,
|
INCOMINGMATERIALEXCEPTION = -4,
|
}
|
}
|