Sic.Framework-Nanjing-Baishi/MECF.Framework.Common/Aitex/Core/RT/DataCollection/HighPerformance/DataBuffer.cs

123 lines
3.1 KiB
C#

using Aitex.Core.RT.Log;
using Aitex.Core.Util;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Aitex.Core.RT.DataCenter;
namespace Aitex.Core.RT.DataCollection.HighPerformance
{
/// <summary>
/// 数据收集器对象,用于收集在<see cref="DataManager"/>中注册的数据源的数据。
/// </summary>
public class DataBuffer<T> : IDataBuffer
{
#region Variables
private readonly Dictionary<long, string> _buffer = new ();
private readonly R_TRIG _rTrigReadFailed = new ();
#endregion
#region Constructors
public DataBuffer(int index, string name, Func<object> read)
{
Index = index;
Name = name;
Read = read;
}
#endregion
#region Properties
/// <summary>
/// 返回数据获取器的序号。
/// </summary>
public int Index { get; }
/// <summary>
/// 返回数据获取器名称。
/// </summary>
public string Name { get; }
public Type ValueType => typeof(T);
/// <summary>
/// 返回数据获取器。
/// </summary>
public Func<object> Read{ get; }
/// <summary>
/// 返回缓存数据的长度。
/// </summary>
internal int CacheCount => _buffer.Count;
#endregion
#region Methods
private string ReadAndFormatValue()
{
try
{
var value = (T)Read.Invoke();
return DataTraceHelper.Format(value);
}
catch (Exception ex)
{
Debug.Assert(false, $"Unable to cache data [{Name}], {ex.Message}");
return "'0'";
}
}
/// <summary>
/// 缓存数据。
/// </summary>
/// <param name="timestamp"></param>
public void Cache(long timestamp)
{
try
{
_buffer[timestamp] = ReadAndFormatValue();
_rTrigReadFailed.CLK = false;
}
catch (Exception ex)
{
// 首次发生错误时记录日志。
_rTrigReadFailed.CLK = true;
if(_rTrigReadFailed.Q)
LOG.Error($"数据获取器 {Name} 在 {timestamp} 时发生错误。", ex);
_buffer[timestamp] = string.Empty;
}
}
/// <summary>
/// 获取指定时间戳的数据。
/// </summary>
/// <param name="timestamp">时间戳。</param>
/// <returns></returns>
public string Get(long timestamp)
{
if (_buffer.TryGetValue(timestamp, out var value))
{
_buffer.Remove(timestamp);
return value;
}
else
{
return default;
}
}
public override string ToString()
{
return $"[{Index}] {Name}, {ValueType.Name}";
}
#endregion
}
}