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
|
||
}
|
||
} |