Bläddra i källkod

20260206001 添加了RingBuffer自定义多线程队列,性能未测试

向羽 孟 2 veckor sedan
förälder
incheckning
db3dc70eda

+ 1 - 0
MvvmScaffoldFrame48.DLL/MvvmScaffoldFrame48.Dll.csproj

@@ -89,6 +89,7 @@
     <Compile Include="ImageAlgorithm\ProcessingAlgorithm_CCDShuLi.cs" />
     <Compile Include="LogTools\TxtLog.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="SystemTools\RingBuffer.cs" />
     <Compile Include="SystemTools\SystemRunTimeTools.cs" />
     <Compile Include="ThreadManager\CameraGroup.cs" />
     <Compile Include="ThreadManager\CommunicationThread.cs" />

+ 57 - 0
MvvmScaffoldFrame48.DLL/SystemTools/RingBuffer.cs

@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MvvmScaffoldFrame48.DLL.SystemTools
+{
+    public sealed class RingBuffer<T>
+    {
+        private readonly T[] _buffer;
+        private int _writeIndex;
+        private int _readIndex;
+        private int _count;
+        private readonly int _capacity;
+        private readonly object _lock = new object();
+
+        public RingBuffer(int capacity)
+        {
+            _capacity = capacity;
+            _buffer = new T[capacity];
+        }
+
+        public bool TryEnqueue(T item)
+        {
+            lock (_lock)
+            {
+                if (_count >= _capacity) return false;
+
+                var index = (_readIndex + _count) % _capacity;
+                _buffer[index] = item;
+                _count++;
+                return true;
+            }
+        }
+
+        public bool TryDequeue(out T result)
+        {
+            lock (_lock)
+            {
+                if (_count <= 0)
+                {
+                    result = default(T);
+                    return false;
+                }
+
+                result = _buffer[_readIndex];
+                _buffer[_readIndex] = default(T); // 避免内存泄漏
+                _readIndex = (_readIndex + 1) % _capacity;
+                _count--;
+                return true;
+            }
+        }
+
+        public int Count => _count;
+    }
+}

+ 83 - 2
MvvmScaffoldFrame48.DLL/ThreadManager/CameraGroup.cs

@@ -1,6 +1,7 @@
 // CameraGroup.cs 相机组线程管理类,控制相机采集和识别的线程运行,开放有算法的接口
 using MvCameraControl;
 using MvvmScaffoldFrame48.DLL.CameraTools;
+using MvvmScaffoldFrame48.DLL.SystemTools;
 using MvvmScaffoldFrame48.Model.ResultModel;
 using MvvmScaffoldFrame48.Model.StorageModel.SystemConfig;
 using System;
@@ -30,8 +31,10 @@ namespace MvvmScaffoldFrame48.DLL.ThreadManager
         public Task CameraTask { get; set; }
         //图像处理线程
         public Task ProcessingTask { get; set; }
-        //图像队列
+        //图像队列-ConcurrentQueue
         public ConcurrentQueue<IImage> ImageQueue { get; set; }
+        //图像队列-自定义RingBuffer
+        public RingBuffer<IImage> ImageRingBuffer { get; set; }
         //信号量
         public SemaphoreSlim QueueSemaphore { get; set; }
         //取消令牌
@@ -71,9 +74,10 @@ namespace MvvmScaffoldFrame48.DLL.ThreadManager
             // 根据配置加载算法
             LoadAlgorithmFromConfiguration();
 
-            Camera.FrameGrabbedEvent += CameraCaptureLoop;
+            //ImageRingBuffer = new RingBuffer<IImage>(300);
 
             //Camera.StartReceiveFuntion();
+            Camera.FrameGrabbedEvent += CameraCaptureLoop;
             Camera.StartReceiveFuntionSetFrameGrabedEvent();
 
             // 重置取消令牌
@@ -326,6 +330,34 @@ namespace MvvmScaffoldFrame48.DLL.ThreadManager
             }
         }
 
+        /// <summary>
+        /// 相机回调取图
+        /// 更换了存储图像的队列
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void CameraCaptureLoop2(object sender, FrameGrabbedEventArgs e)
+        {
+            try
+            {
+                // 将图像放入队列
+                ImageRingBuffer.TryEnqueue(e.FrameOut.Image.Clone() as IImage);
+                double QuTuYanshi = (DateTime.Now - FromUnixTimestamp((long)e.FrameOut.HostTimeStamp)).TotalMilliseconds;
+                //Console.WriteLine($"相机 {CameraId} 采集到图像,帧号{imageData.FrameNum}");
+                if (QuTuYanshi > 12)
+                {
+                    Console.WriteLine($"识别落后时间{QuTuYanshi}");
+                }
+                QueueSemaphore.Release(); // 通知处理线程有新数据
+                e.FrameOut.Dispose();
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine($"相机 {CameraId} 采集异常: {ex.Message}");
+            }
+        }
+
+
         /// <summary>
         /// 图像处理循环
         /// 适用取图频率不高的处理,或者处理速度远快于取图速度的方法
@@ -417,6 +449,55 @@ namespace MvvmScaffoldFrame48.DLL.ThreadManager
                 Console.WriteLine($"相机 {CameraId} 处理异常: {ex.Message}");
             }
         }
+
+        private async void ImageProcessingbatchLoop2(CancellationToken token)
+        {
+            const int batchSize = 5; // 每批处理的最大图像数量
+            var batch = new List<IImage>(batchSize); // 存储当前批次的图像
+
+            try
+            {
+                while (!token.IsCancellationRequested)
+                {
+                    // 等待至少一张图像数据
+                    await QueueSemaphore.WaitAsync(token);
+
+                    // 收集一批图像(严格按队列顺序)
+                    while (batch.Count < batchSize && ImageRingBuffer.TryDequeue(out IImage imageData))
+                    {
+                        batch.Add(imageData);
+                        if (ImageRingBuffer.Count > 0)
+                        {
+                            QueueSemaphore.Release(); // 提前释放信号量,唤醒其他等待线程
+                        }
+                    }
+
+                    // 顺序处理当前批次的所有图像
+                    foreach (var image in batch)
+                    {
+                        ProcessImage(image, CameraId); // 严格按顺序执行处理逻辑
+                        image.Dispose(); // 处理完成后立即释放资源
+                    }
+
+                    // 清空当前批次,准备下一轮处理
+                    batch.Clear();
+
+                    // 如果队列为空,短暂休眠以避免过度占用CPU
+                    if (ImageRingBuffer.Count == 0)
+                    {
+                        await Task.Delay(1, token); // 固定短时间休眠
+                    }
+                }
+            }
+            catch (OperationCanceledException)
+            {
+                // 线程被取消,正常退出
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine($"相机 {CameraId} 处理异常: {ex.Message}");
+            }
+        }
         #endregion
 
         public DateTime FromUnixTimestamp(long timestamp, bool isMilliseconds = false)