using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ThreadManagerTest { public class ThreadManager { private readonly CameraGroup[] _cameraGroups = new CameraGroup[4]; private CancellationTokenSource _communicationCts; private CancellationTokenSource _displayCts; private Task _communicationTask; private Task _displayTask; private bool _isCommunicationRunning = false; private bool _isDisplayRunning = false; // 用于存储待发送的结果数据的队列 private readonly ConcurrentQueue _resultQueue = new ConcurrentQueue(); private readonly SemaphoreSlim _resultSemaphore = new SemaphoreSlim(0); public ThreadManager() { // 初始化四个相机组 for (int i = 0; i < 4; i++) { _cameraGroups[i] = new CameraGroup { CameraId = i, ImageQueue = new ConcurrentQueue(), QueueSemaphore = new SemaphoreSlim(0), CancellationTokenSource = new CancellationTokenSource() }; // 订阅处理结果事件 _cameraGroups[i].ProcessResultAvailable += OnProcessResultAvailable; } } /// /// 处理结果事件处理器 /// 当任一相机组产生处理结果时都会调用此方法 /// private void OnProcessResultAvailable(object sender, ProcessResultEventArgs e) { // 将结果数据加入队列 _resultQueue.Enqueue(e); // 通知通信线程有新数据 _resultSemaphore.Release(); } /// /// 通信线程循环 - 修改版 /// private async void CommunicationLoop(CancellationToken token) { try { while (!token.IsCancellationRequested) { // 等待结果数据 await _resultSemaphore.WaitAsync(token); // 检查是否有待发送的结果 if (_resultQueue.TryDequeue(out ProcessResultEventArgs result)) { // 发送结果数据 SendResultToCommunicationDevice(result); } // 1ms休眠 await Task.Delay(1, token); } } catch (OperationCanceledException) { // 线程被取消,正常退出 } catch (Exception ex) { Console.WriteLine($"通信线程异常: {ex.Message}"); } } /// /// 发送结果数据到通信设备 /// private void SendResultToCommunicationDevice(ProcessResultEventArgs result) { // 实际的通信发送逻辑 Console.WriteLine($"发送相机{result.CameraId}的结果数据: " + $"目标数={((ProcessResultData)result.ResultData).TargetCount}, " + $"时间={result.Timestamp}"); // 这里实现实际的串口、网络或其他通信协议发送逻辑 } /// /// 启动指定相机组(包括采集和处理线程) /// /// 相机ID (0-3) public void StartCameraGroup(int cameraId) { if (cameraId < 0 || cameraId >= 4) throw new ArgumentException("相机ID必须在0-3之间"); var group = _cameraGroups[cameraId]; if (group.IsRunning) return; // 重置取消令牌 group.CancellationTokenSource = new CancellationTokenSource(); var token = group.CancellationTokenSource.Token; // 启动相机采集线程 group.CameraTask = Task.Factory.StartNew(() => CameraCaptureLoop(group, token), token, TaskCreationOptions.LongRunning, TaskScheduler.Default); // 启动图像处理线程 group.ProcessingTask = Task.Factory.StartNew(() => ImageProcessingLoop(group, token), token, TaskCreationOptions.LongRunning, TaskScheduler.Default); group.IsRunning = true; Console.WriteLine($"相机组 {cameraId} 已启动"); } /// /// 停止指定相机组 /// /// 相机ID (0-3) public async void StopCameraGroup(int cameraId) { if (cameraId < 0 || cameraId >= 4) throw new ArgumentException("相机ID必须在0-3之间"); var group = _cameraGroups[cameraId]; if (!group.IsRunning) return; // 发送取消信号 group.CancellationTokenSource.Cancel(); // 等待线程完成 try { if (group.CameraTask != null) await group.CameraTask; if (group.ProcessingTask != null) await group.ProcessingTask; } catch (OperationCanceledException) { // 正常取消,忽略异常 } group.IsRunning = false; Console.WriteLine($"相机组 {cameraId} 已停止"); } /// /// 启动通信线程 /// public void StartCommunicationThread() { if (_isCommunicationRunning) return; _communicationCts = new CancellationTokenSource(); var token = _communicationCts.Token; _communicationTask = Task.Factory.StartNew(() => CommunicationLoop(token), token, TaskCreationOptions.LongRunning, TaskScheduler.Default); _isCommunicationRunning = true; Console.WriteLine("通信线程已启动"); } /// /// 停止通信线程 /// public async void StopCommunicationThread() { if (!_isCommunicationRunning) return; _communicationCts.Cancel(); try { if (_communicationTask != null) await _communicationTask; } catch (OperationCanceledException) { // 正常取消,忽略异常 } _isCommunicationRunning = false; Console.WriteLine("通信线程已停止"); } /// /// 启动显示线程 /// public void StartDisplayThread() { if (_isDisplayRunning) return; _displayCts = new CancellationTokenSource(); var token = _displayCts.Token; _displayTask = Task.Factory.StartNew(() => DisplayLoop(token), token, TaskCreationOptions.LongRunning, TaskScheduler.Default); _isDisplayRunning = true; Console.WriteLine("显示线程已启动"); } /// /// 停止显示线程 /// public async void StopDisplayThread() { if (!_isDisplayRunning) return; _displayCts.Cancel(); try { if (_displayTask != null) await _displayTask; } catch (OperationCanceledException) { // 正常取消,忽略异常 } _isDisplayRunning = false; Console.WriteLine("显示线程已停止"); } /// /// 启动所有线程组 /// public void StartAll() { // 启动所有相机组 for (int i = 0; i < 4; i++) { StartCameraGroup(i); } // 启动通信和显示线程 StartCommunicationThread(); StartDisplayThread(); } /// /// 停止所有线程组 /// public void StopAll() { // 停止所有相机组 for (int i = 0; i < 4; i++) { StopCameraGroup(i); } // 停止通信和显示线程 StopCommunicationThread(); StopDisplayThread(); } /// /// 检查指定相机组是否正在运行 /// /// 相机ID /// 运行状态 public bool IsCameraGroupRunning(int cameraId) { if (cameraId < 0 || cameraId >= 4) return false; return _cameraGroups[cameraId].IsRunning; } /// /// 检查通信线程是否正在运行 /// public bool IsCommunicationRunning => _isCommunicationRunning; /// /// 检查显示线程是否正在运行 /// public bool IsDisplayRunning => _isDisplayRunning; #region 线程执行逻辑 /// /// 相机采集循环 /// private void CameraCaptureLoop(CameraGroup group, CancellationToken token) { int frameCount = 0; try { while (!token.IsCancellationRequested) { // 模拟相机图像采集(无休眠,持续采集) var imageData = new ImageData { CameraId = group.CameraId, RawData = new byte[1024], // 模拟图像数据 Timestamp = DateTime.Now, FrameNumber = frameCount++ }; // 将图像放入队列 group.ImageQueue.Enqueue(imageData); group.QueueSemaphore.Release(); // 通知处理线程有新数据 // 这里不添加休眠,保持最大帧率采集 } } catch (OperationCanceledException) { // 线程被取消,正常退出 } catch (Exception ex) { Console.WriteLine($"相机 {group.CameraId} 采集异常: {ex.Message}"); } } /// /// 图像处理循环 /// private async void ImageProcessingLoop(CameraGroup group, CancellationToken token) { try { while (!token.IsCancellationRequested) { // 等待图像数据 await group.QueueSemaphore.WaitAsync(token); // 从队列获取图像 if (group.ImageQueue.TryDequeue(out ImageData imageData)) { // 执行图像处理逻辑 ProcessImage(imageData,group); // 可以根据队列长度决定是否短暂休眠以避免过度占用CPU if (group.ImageQueue.Count == 0) { await Task.Delay(1, token); // 短暂让出CPU } } } } catch (OperationCanceledException) { // 线程被取消,正常退出 } catch (Exception ex) { Console.WriteLine($"相机 {group.CameraId} 处理异常: {ex.Message}"); } } /// /// 图像处理实现 - 修改版 /// private void ProcessImage(ImageData imageData, CameraGroup group) { var stopwatch = System.Diagnostics.Stopwatch.StartNew(); // 执行图像处理逻辑 var result = PerformImageAnalysis(imageData); stopwatch.Stop(); // 创建处理结果数据 var resultData = new ProcessResultData { TargetCount = result.Targets.Count, TargetPositions = result.Targets.Select(t => t.Position).ToList(), ProcessingTimeMs = stopwatch.ElapsedMilliseconds, FrameNumber = imageData.FrameNumber, ConfidenceScore = result.AverageConfidence }; // 发送处理结果 group.SendProcessResult(resultData); Console.WriteLine($"相机 {imageData.CameraId} 处理帧 {imageData.FrameNumber},发现 {result.Targets.Count} 个目标"); } /// /// 图像分析模拟方法 /// private ImageAnalysisResult PerformImageAnalysis(ImageData imageData) { // 模拟图像分析过程 Thread.Sleep(10); // 模拟处理时间 // 模拟分析结果 return new ImageAnalysisResult { Targets = new List { new TargetInfo { Position = new Point { X = 100, Y = 150 }, Confidence = 0.95 }, new TargetInfo { Position = new Point { X = 200, Y = 300 }, Confidence = 0.87 } }, AverageConfidence = 0.91 }; } /// /// 显示线程循环 /// private async void DisplayLoop(CancellationToken token) { var stopwatch = System.Diagnostics.Stopwatch.StartNew(); long targetFrameTime = 1000 / 24; // 24fps对应的时间间隔(ms) try { while (!token.IsCancellationRequested) { stopwatch.Restart(); // 执行显示逻辑 UpdateDisplay(); stopwatch.Stop(); long elapsed = stopwatch.ElapsedMilliseconds; // 动态调整休眠时间以维持24fps long sleepTime = Math.Max(0, targetFrameTime - elapsed); if (sleepTime > 0) { await Task.Delay((int)sleepTime, token); } } } catch (OperationCanceledException) { // 线程被取消,正常退出 } catch (Exception ex) { Console.WriteLine($"显示线程异常: {ex.Message}"); } } /// /// 显示更新实现 /// private void UpdateDisplay() { // 实现显示更新逻辑 Console.WriteLine("更新显示画面"); } #endregion } /// /// 相机组配置和状态管理类 /// 管理单个相机的采集和处理线程及相关资源 /// public class CameraGroup { public int CameraId { get; set; } public bool IsRunning { get; set; } public CancellationTokenSource CancellationTokenSource { get; set; } public Task CameraTask { get; set; } public Task ProcessingTask { get; set; } public ConcurrentQueue ImageQueue { get; set; } public SemaphoreSlim QueueSemaphore { get; set; } // 结果发送事件,当图像处理完成时触发 public event EventHandler ProcessResultAvailable; /// /// 发送处理结果到通信线程的方法 /// 多个线程可以共用此方法 /// /// 处理结果数据 public void SendProcessResult(object resultData) { var eventArgs = new ProcessResultEventArgs { CameraId = this.CameraId, ResultData = resultData, Timestamp = DateTime.Now }; // 触发事件,通知订阅者有新的处理结果 ProcessResultAvailable?.Invoke(this, eventArgs); } } /// /// 处理结果事件参数类 /// 包含相机ID和处理结果数据 /// public class ProcessResultEventArgs : EventArgs { /// /// 相机ID /// public int CameraId { get; set; } /// /// 处理结果数据 /// public object ResultData { get; set; } /// /// 结果生成时间戳 /// public DateTime Timestamp { get; set; } } /// /// 处理结果数据结构示例 /// public class ProcessResultData { /// /// 检测到的目标数量 /// public int TargetCount { get; set; } /// /// 目标位置坐标列表 /// public List TargetPositions { get; set; } /// /// 处理耗时(毫秒) /// public long ProcessingTimeMs { get; set; } /// /// 图像帧编号 /// public int FrameNumber { get; set; } /// /// 置信度评分 /// public double ConfidenceScore { get; set; } } /// /// 点坐标结构 /// public struct Point { public float X { get; set; } public float Y { get; set; } } /// /// 图像数据结构 /// public class ImageData { public int CameraId { get; set; } public byte[] RawData { get; set; } public DateTime Timestamp { get; set; } public int FrameNumber { get; set; } } /// /// 图像分析结果类 /// public class ImageAnalysisResult { public List Targets { get; set; } public double AverageConfidence { get; set; } } /// /// 目标信息类 /// public class TargetInfo { public Point Position { get; set; } public double Confidence { get; set; } } }