Browse Source

feat: 部分计算变量写加锁

master
fajiao 2 years ago
parent
commit
de8375471e
  1. 37
      Cis.Application/Core/Algo/MarkSearcherBase.cs
  2. 84
      Cis.Application/Core/Center/CameraDataCenter.cs
  3. 2
      Cis.Core/Extension/ObjectExtension.cs

37
Cis.Application/Core/Algo/MarkSearcherBase.cs

@ -1,4 +1,5 @@
using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra;
using System.Collections.Concurrent;
using System.Drawing; using System.Drawing;
namespace Cis.Application.Core; namespace Cis.Application.Core;
@ -12,7 +13,15 @@ public abstract class MarkSearcherBase
/// </summary> /// </summary>
protected CameraCalcInfo _cameraCalcInfo { get; set; } protected CameraCalcInfo _cameraCalcInfo { get; set; }
protected List<MarkLabelCalcInfo> _markLabelInfoList { get; set; } = new(); /// <summary>
/// _markLabelInfoList 锁对象,写锁
/// </summary>
private static readonly object mliListLock = new();
/// <summary>
/// 需要计算的 markLabelInfo 列表
/// </summary>
protected ConcurrentDictionary<long, MarkLabelCalcInfo> _markLabelInfoDict { get; set; } = new();
protected MatrixBuilder<double> MBuilder { get; set; } = Matrix<double>.Build; protected MatrixBuilder<double> MBuilder { get; set; } = Matrix<double>.Build;
@ -38,10 +47,10 @@ public abstract class MarkSearcherBase
{ {
List<MarkLabelCalcResult> resultList = new(); List<MarkLabelCalcResult> resultList = new();
if (World2CameraMatrix == null || _markLabelInfoList.Count == 0) if (World2CameraMatrix == null || _markLabelInfoDict.IsEmpty)
return resultList; return resultList;
foreach (MarkLabelCalcInfo item in _markLabelInfoList) foreach (MarkLabelCalcInfo item in _markLabelInfoDict.Values)
{ {
Matrix<double> labelC2WMatrix = ConvertCameraToWorld(item); Matrix<double> labelC2WMatrix = ConvertCameraToWorld(item);
Matrix<double> labelPointMatrix = MBuilder.DenseOfArray(new double[,] Matrix<double> labelPointMatrix = MBuilder.DenseOfArray(new double[,]
@ -213,18 +222,30 @@ public abstract class MarkSearcherBase
} }
} }
public void AddMarkLabelCalcInfo(MarkLabelCalcInfo markLabelCalcInfo) public bool AddMarkLabelCalcInfo(MarkLabelCalcInfo info)
{
lock (mliListLock)
{ {
_markLabelInfoList.Add(markLabelCalcInfo); if (_markLabelInfoDict.ContainsKey(info.Id))
return false;
return _markLabelInfoDict.TryAdd(info.Id, info);
}
} }
public bool ExistsMarkLabelCalcInfo(object id) public bool DeleteMarkLabelCalcInfo(long id)
{ {
foreach (MarkLabelCalcInfo info in _markLabelInfoList) lock (mliListLock)
{ {
if (info.Id.Equals(id)) if (!_markLabelInfoDict.ContainsKey(id))
return true; return true;
return _markLabelInfoDict.Remove(id);
}
} }
public bool ExistsMarkLabelCalcInfo(long id)
{
if (_markLabelInfoDict.ContainsKey(id))
return true;
return false; return false;
} }

84
Cis.Application/Core/Center/CameraDataCenter.cs

@ -17,11 +17,6 @@ public class CameraDataCenter
private Thread _thread { get; set; } private Thread _thread { get; set; }
/// <summary>
/// (cbCameraId, MarkSearcherBase)
/// </summary>
private ConcurrentDictionary<long, MarkSearcherBase> _markSearcherDict { get; set; } = new();
/// <summary> /// <summary>
/// (cbCameraId, cbCameraIp) /// (cbCameraId, cbCameraIp)
/// </summary> /// </summary>
@ -37,6 +32,22 @@ public class CameraDataCenter
/// </summary> /// </summary>
private ConcurrentDictionary<string, PtzInfo> _cameraPtzInfoDict { get; set; } = new(); private ConcurrentDictionary<string, PtzInfo> _cameraPtzInfoDict { get; set; } = new();
/// <summary>
/// _markSearcherDict 锁对象,写锁
/// </summary>
private static readonly ReaderWriterLockSlim msDictLock = new();
/// <summary>
/// (cbCameraId, MarkSearcherBase)
/// </summary>
private ConcurrentDictionary<long, MarkSearcherBase> _markSearcherDict { get; set; } = new();
/// <summary>
/// (cameraId, List(MarkLabelCalcResult))
/// </summary>
private ConcurrentDictionary<long, List<MarkLabelCalcResult>> _markLabelCalcResultListDict { get; set; } = new();
#endregion Attr #endregion Attr
public CameraDataCenter() public CameraDataCenter()
@ -105,6 +116,7 @@ public class CameraDataCenter
if (ptzInfo == null) continue; if (ptzInfo == null) continue;
markSearcher.UpdateCameraCalcInfo(ptzInfo); markSearcher.UpdateCameraCalcInfo(ptzInfo);
List<MarkLabelCalcResult> resultList = markSearcher.Calc(); List<MarkLabelCalcResult> resultList = markSearcher.Calc();
_markLabelCalcResultListDict[cameraId] = resultList;
} }
} }
@ -119,11 +131,18 @@ public class CameraDataCenter
/// <returns></returns> /// <returns></returns>
public bool ActiveCamera(long cameraId) public bool ActiveCamera(long cameraId)
{ {
try
{
msDictLock.EnterWriteLock();
if (_markSearcherDict.ExistsKey(cameraId))
return false;
// 获取 cbCamera
CbCamera cbCamera = _cbCameraRep.GetById(cameraId); CbCamera cbCamera = _cbCameraRep.GetById(cameraId);
if (cbCamera == null) return false; if (cbCamera == null) return false;
// 获取 tbPtzCamera
TbPtzCamera tbPtzCamera; TbPtzCamera tbPtzCamera;
string cameraIp = cbCamera.Ip; string cameraIp = cbCamera.Ip;
if (!_tbPtzCameraDict.IsExistKey(cameraIp)) if (!_tbPtzCameraDict.ExistsKey(cameraIp))
{ {
tbPtzCamera = _tbPtzCameraRep.GetFirst(u => u.Ip == cameraIp); tbPtzCamera = _tbPtzCameraRep.GetFirst(u => u.Ip == cameraIp);
if (tbPtzCamera == null) return false; if (tbPtzCamera == null) return false;
@ -133,10 +152,15 @@ public class CameraDataCenter
{ {
tbPtzCamera = _tbPtzCameraDict[cameraIp]; tbPtzCamera = _tbPtzCameraDict[cameraIp];
} }
// 存储 cbCamera id 对应 ip 关系
_cbCameraId2IpDict[cbCamera.Id] = cameraIp; _cbCameraId2IpDict[cbCamera.Id] = cameraIp;
// 创建 cameraCalcInfo
CameraCalcInfo cameraCalcInfo = CameraCalcInfo.New(cameraId, _ptzServerApi.GetPtzInfo(tbPtzCamera.Id)); CameraCalcInfo cameraCalcInfo = CameraCalcInfo.New(cameraId, _ptzServerApi.GetPtzInfo(tbPtzCamera.Id));
// 创建 markSeacher
HikMarkSeacher markSeacher = new(cameraCalcInfo); HikMarkSeacher markSeacher = new(cameraCalcInfo);
// 获取 cmMarkLabel 列表
List<CmMarkLabel> cmMarkLabelList = _cmMarkLableRep.GetList(u => u.CbCameraId == cameraId); List<CmMarkLabel> cmMarkLabelList = _cmMarkLableRep.GetList(u => u.CbCameraId == cameraId);
// 将 cmMarkLabel 一一添加到 markSeacher
foreach (CmMarkLabel item in cmMarkLabelList) foreach (CmMarkLabel item in cmMarkLabelList)
{ {
MarkLabelCalcInfo markLabelCalcInfo = MarkLabelCalcInfo.New( MarkLabelCalcInfo markLabelCalcInfo = MarkLabelCalcInfo.New(
@ -149,7 +173,13 @@ public class CameraDataCenter
); );
markSeacher.AddMarkLabelCalcInfo(markLabelCalcInfo); markSeacher.AddMarkLabelCalcInfo(markLabelCalcInfo);
} }
// 将 markSeacher 放入字典
_markSearcherDict[cameraId] = markSeacher; _markSearcherDict[cameraId] = markSeacher;
}
finally
{
msDictLock.ExitWriteLock();
}
return true; return true;
} }
@ -160,12 +190,52 @@ public class CameraDataCenter
/// <returns></returns> /// <returns></returns>
public bool DeActiveCamera(long cameraId) public bool DeActiveCamera(long cameraId)
{ {
try
{
msDictLock.EnterWriteLock();
_markSearcherDict.Remove(cameraId);
_markLabelCalcResultListDict.Remove(cameraId);
}
finally
{
msDictLock.ExitWriteLock();
}
return true;
}
public bool AddCameraMarkLabel(long cameraId, long markLabelId)
{
if (!_markSearcherDict.ExistsKey(cameraId))
return false;
MarkSearcherBase markSearcher = _markSearcherDict[cameraId];
if (markSearcher.ExistsMarkLabelCalcInfo(markLabelId))
return false;
CmMarkLabel label = _cmMarkLableRep.GetById(markLabelId);
if (label == null)
return false; return false;
MarkLabelCalcInfo markLabelCalcInfo = MarkLabelCalcInfo.New(
label.Id,
PtzInfo.New(label.PanPosition, label.TiltPosition, label.ZoomPosition),
label.CanvasWidth,
label.CanvasHeight,
label.CanvasLeft,
label.CanvasTop
);
return markSearcher.AddMarkLabelCalcInfo(markLabelCalcInfo);
} }
public bool UpdateCamera(long cameraId, long markLabelId) public bool DeleteCameraMarkLabel(long cameraId, long marklabelId)
{ {
if (!_markSearcherDict.ExistsKey(cameraId))
return false; return false;
MarkSearcherBase markSearcher = _markSearcherDict[cameraId];
return markSearcher.DeleteMarkLabelCalcInfo(marklabelId);
}
public List<MarkLabelCalcResult> GetMarkLabelCalcResults(long cameraId)
{
return null;
} }
#endregion external call #endregion external call

2
Cis.Core/Extension/ObjectExtension.cs

@ -139,7 +139,7 @@ public static class ObjectExtension
return sc != null; return sc != null;
} }
public static bool IsExistKey(this IDictionary dict, object key) public static bool ExistsKey(this IDictionary dict, object key)
{ {
foreach (object item in dict.Keys) foreach (object item in dict.Keys)
{ {

Loading…
Cancel
Save