72 lines
2.1 KiB
C#
72 lines
2.1 KiB
C#
|
|
using Core.WcfProtocol;
|
|||
|
|
using System.Collections.Concurrent;
|
|||
|
|
|
|||
|
|
namespace SHH.MjpegPlayer
|
|||
|
|
{
|
|||
|
|
/// <summary>图片通道集合</summary>
|
|||
|
|
public class ImageChannels
|
|||
|
|
{
|
|||
|
|
#region Channels
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 通道信息 (线程安全版本)
|
|||
|
|
/// </summary>
|
|||
|
|
// [修复] 使用 ConcurrentDictionary 替代 Dictionary,防止多线程读写(如推流和接收图片同时进行)时崩溃
|
|||
|
|
public ConcurrentDictionary<string, ImageChannel> Channels { get; set; }
|
|||
|
|
= new ConcurrentDictionary<string, ImageChannel>();
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region Do
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 处置图片
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="req"></param>
|
|||
|
|
/// <param name="key"></param>
|
|||
|
|
public ImageChannel? Do(UploadImageRequest req, string key)
|
|||
|
|
{
|
|||
|
|
// [修复] 使用 GetOrAdd 原子操作,无需 lock,彻底解决并发冲突
|
|||
|
|
// 如果 key 不存在,则创建新通道;如果存在,则返回现有通道
|
|||
|
|
var chn = Channels.GetOrAdd(key, k => new ImageChannel
|
|||
|
|
{
|
|||
|
|
DeviceId = req.Id,
|
|||
|
|
Name = req.Name,
|
|||
|
|
Type = req.Type,
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 更新指定信息 (直接属性赋值是原子性的,无需锁)
|
|||
|
|
chn.IpAddress = req.IpAddress;
|
|||
|
|
chn.ProcId = req.ProcId;
|
|||
|
|
chn.ImageWidth = req.ImageWidth;
|
|||
|
|
chn.ImageHeight = req.ImageHeight;
|
|||
|
|
chn.UpdateTime = req.Time;
|
|||
|
|
|
|||
|
|
return chn;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region Get
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取通道信息
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="deviceId"></param>
|
|||
|
|
/// <param name="aiTypeCode"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public ImageChannel? Get(string deviceId, string aiTypeCode)
|
|||
|
|
{
|
|||
|
|
string key = $"{deviceId}#{aiTypeCode}";
|
|||
|
|
|
|||
|
|
// [修复] ConcurrentDictionary 读取原本就是线程安全的
|
|||
|
|
if (Channels.TryGetValue(key, out var val))
|
|||
|
|
{
|
|||
|
|
return val;
|
|||
|
|
}
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
}
|
|||
|
|
}
|