using Cognex.VisionPro;
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

namespace ConVX.VXData
{
    public class DataPostbox
    {
        #region 字段
        /// <summary>
        /// 图像队列:来存储数据信封（CogImage8Grey）的队列。
        /// </summary>
        private ConcurrentQueue<CogImage8Grey> _queue;
        /// <summary>
        /// 判断线程状态
        /// </summary>
        //private AutoResetEvent _autoReset = null;
        /// <summary>
        /// 线程
        /// </summary>
        private Task _task;
        /// <summary>
        /// 控制任务启动
        /// </summary>
        private CancellationTokenSource RuningToken;
        #endregion

        #region 事件
        /// <summary>
        /// 当有信件被派发时触发的事件。
        /// </summary>
        public event Action<CogImage8Grey> DeliverLetterEvent;
        /// <summary>
        /// 当发生错误时触发的事件。
        /// </summary>
        public event Action<string> ErrorEvent;
        #endregion

        #region 公开的方法
        /// <summary>
        /// 构造函数
        /// </summary>
        public DataPostbox()
        {
            _queue = new ConcurrentQueue<CogImage8Grey>();
        }
        /// <summary>
        /// 启动派发
        /// </summary>
        public void Start()
        {
            RuningToken = new CancellationTokenSource();//创建启动
            _task = new Task(() => EnvelopeProcessing(), RuningToken.Token);
            _task.Start();//线程启动
        }
        /// <summary>
        /// 停止派发
        /// </summary>
        public async void Stop()
        {
            try
            {
                RuningToken.Cancel();
                await _task;
            }
            catch (OperationCanceledException ex)
            {
                _task.Dispose();
                _task = null;
            }
        }
        /// <summary>
        /// 邮寄信件
        /// </summary>
        /// <param name="envelope">信息信件</param>
        public void Mailing(CogImage8Grey envelope)
        {
            _queue.Enqueue(envelope);
        }
        #endregion

        #region 数据处理线程
        private void EnvelopeProcessing()
        {
            while (!RuningToken.IsCancellationRequested)
            {
                if (_queue.IsEmpty)
                {
                    Thread.Sleep(1);
                }
                else
                {
                    try
                    {
                        CogImage8Grey envelope;
                        if (_queue.TryDequeue(out envelope))
                        {
                            DeliverLetterEvent(envelope);
                        }
                    }
                    catch (Exception ex)
                    {
                        ErrorEvent(string.Format("数据队列出队失败，原因：{0}", ex.Message.ToString()));
                    }
                }
            }
        }
        #endregion
    }
}
