

using System.Threading;

namespace CsvCount_ES
{
    /// <summary>
    ///  一个线程池、定义线程数、的框架。
    /// </summary>
    public class SingleThreadRunner
    {
        private bool signalClose;
        private bool signalWork;
        //工作项
        private WorkItem currentWorkItem;
       //自己项目的线程池类
        public ThreadPool ThreadPool { get; set; }
        public Thread Thread { get; set; }

        /// <summary>
        ///    实例化
        /// </summary>
        public SingleThreadRunner()
        {
        }

        /// <summary>
        ///    实例化
        /// </summary> 
        public SingleThreadRunner(ThreadPool threadPool)
        {
            ThreadPool = threadPool;
        }

        /// <summary>
        ///   处理和设置各种信号的工作。
        /// </summary>
        public void DoWork()
        {
            var spinWait = new SpinWait();
            while (!signalClose)
            {
                if (signalWork)
                {
                    while (currentWorkItem != null && !signalClose)
                    {
                        // 启动负载
                        currentWorkItem.Result = currentWorkItem.Delegate(currentWorkItem.DelegateInputParameters);

                        // 设置完成
                        currentWorkItem.IsCompleted = true;

                        //设置回调函数.
                        if (currentWorkItem.AsyncCallback != null)
                        {
                            currentWorkItem.AsyncCallback.Invoke(currentWorkItem.Result);
                        }

                        // 让下一个工作项出队列
                        if (ThreadPool.IsDisposeDoneWorkItemsAutomatically)
                        {
                            // 如果还有工作，则自动返回工作项以进行重用。
                            currentWorkItem = ThreadPool.DequeueWorkItemInternal(this, signalWork, currentWorkItem);
                        }
                        else
                        {
                            currentWorkItem = ThreadPool.DequeueWorkItemInternal(this, signalWork);
                        }
                    }
                    // 工作项没有更多的工作，也没有暂停。
                    signalWork = false;
                }
                else
                {
                    spinWait.SpinOnce();
                }
            }
            //线程关闭
            signalClose = false;
        }

        /// <summary>
        /// 立即开始执行。
        /// </summary>
        public void SignalWork(WorkItem workItemToProcess)
        {
            //等待主循环不繁忙，更改currentWorkItem工作项为新传递的参数。
            var spinWait = new SpinWait();
            while (signalWork)
            {
                spinWait.SpinOnce();
                Thread.MemoryBarrier();
            }
            Interlocked.Exchange(ref currentWorkItem, workItemToProcess);
            //InterlockedExChange来实现循环锁的功能，所谓循环锁，就是在线程1中如果要对变量进行操作，要先查看这个变量（或资源）有没有被其它线程用到，如果是，则一直循环，则到其它线程放弃对该变量（或资源）的控制。如果否，直接可以对该变量（或资源）进行操作。 
            signalWork = true;
            Thread.MemoryBarrier();
        }

        /// <summary>
        ///     工作项关闭信号。
        /// </summary>
        public void SignalShutDown()
        {
            signalClose = true;
        }

        /// <summary>
        ///    工作项暂停信号。
        /// </summary>
        public void SignalPause()
        {
            Thread.MemoryBarrier();
            signalWork = false;
            Thread.MemoryBarrier();
        }

        /// <summary>
        ///   工作项复位信号。
        /// </summary>
        public void SignalResume()
        {
            Thread.MemoryBarrier();
            signalWork = true;
            Thread.MemoryBarrier();
        }

        /// <summary>
        ///    中止实例--终止线程。
        /// </summary>
        public void Abort()
        {
            Thread.Abort();
        }
    }
}