优化 Mjpeg 播放

This commit is contained in:
2026-01-22 14:06:44 +08:00
parent c438edfa0d
commit 6661edfc44
4 changed files with 111 additions and 105 deletions

View File

@@ -13,16 +13,20 @@ namespace SHH.MjpegPlayer
/// </summary>
public class MjpegSession : IDisposable
{
#region Defines
private static readonly ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core);
#region Counter
private CancellationTokenSource? _sessionCts;
private SumByTime _sumBySecond = new SumByTime();
/// <summary>
/// 计数器
/// </summary>
/// <summary>计数器</summary>
public SumByTime Counter => _sumBySecond;
// 引入 Disposed 标志位
private volatile bool _isDisposed = false;
#endregion
#region Info
@@ -43,9 +47,6 @@ namespace SHH.MjpegPlayer
#endregion
// [修复] 引入 Disposed 标志位
private volatile bool _isDisposed = false;
#region Constructor
/// <summary>
@@ -150,7 +151,10 @@ namespace SHH.MjpegPlayer
// 初始化最近接收时间,避免刚连接就被判定为超时
LastRecImgTime = DateTime.Now;
Task.Run(() => { DoWorkTask(client); });
// 绑定全局取消令牌,确保系统停止时能立即强制中断所有会话
_sessionCts = new CancellationTokenSource();
Task.Run(() => { DoWorkTask(client, _sessionCts.Token); }, _sessionCts.Token);
}
catch (Exception ex)
{
@@ -162,7 +166,7 @@ namespace SHH.MjpegPlayer
#region DoWorkTask
private void DoWorkTask(TcpClient client)
private void DoWorkTask(TcpClient client, CancellationToken token)
{
try
{
@@ -174,11 +178,12 @@ namespace SHH.MjpegPlayer
#region ,
int iLoc = 0;
while (!client.Connected)
while (!client.Connected && !token.IsCancellationRequested)
{
Thread.Sleep(50);
if (++iLoc > 60) return;
}
if (token.IsCancellationRequested) return;
try
{
@@ -210,7 +215,7 @@ namespace SHH.MjpegPlayer
byte[] boundaryBytes = Encoding.ASCII.GetBytes("\r\n--frame\r\nContent-Type: image/jpeg\r\nContent-Length: ");
byte[] doubleNewLine = Encoding.ASCII.GetBytes("\r\n\r\n");
while (client.Connected && !_isDisposed)
while (client.Connected && !_isDisposed && !token.IsCancellationRequested)
{
try
{
@@ -256,7 +261,8 @@ namespace SHH.MjpegPlayer
stopwatch.Stop();
var needSleep = frameInterval - (int)stopwatch.ElapsedMilliseconds;
if (needSleep > 0) Thread.Sleep(needSleep);
if (needSleep > 0)
Task.Delay(needSleep, token).Wait(token);
}
catch (Exception ex)
{
@@ -333,9 +339,18 @@ namespace SHH.MjpegPlayer
{
if (_isDisposed) return;
_isDisposed = true;
// 释放令牌资源
try
{
_sessionCts?.Cancel();
_sessionCts?.Dispose();
}
catch { }
MjpegStatics.Sessions.RemoveSession(this);
}
#endregion
}
}
}