• 周二. 10 月 8th, 2024

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

多线程实现

admin

11 月 28, 2021

WorkState

    public enum WorkState
    {
        Ready,
        Running,
        Completed
    }

IWork

    public interface IWork
    {
        WorkState State { get; set; }
        void Perform();
    }

关键类WorkQueue

public class WorkQueue
    {
        private List<IWork> _vlstWork = new List<IWork>();

        public void Add(IWork work)
        {
            lock (this)
            {
                _vlstWork.Add(work);
            }
        }

        public int GetCount(WorkState state)
        {
            lock (this)
            {
                int count = 0;
                _vlstWork.ForEach(item =>
                {
                    if (item.State == state)
                        count++;
                });
                return count;
            }
        }

        public IWork GetWork()
        {
            lock(this)
            {
                foreach (IWork work in _vlstWork)
                    if (work.State == WorkState.Ready)
                        return work;
                return null;
            }
        }
    }

重点类ThreadScheduler

public delegate void AllFinishedHandler();
    public class ThreadScheduler
    {
        private readonly int _viConcurrentLimit = 10;
        private WorkQueue _vWorkQueue = null;

        public AllFinishedHandler OnAllFinished = null;

        public WorkQueue WorkQueue
        {
            get { return _vWorkQueue; }
        }
        public int ConcurrentLimit
        {
            get { return _viConcurrentLimit; }
        }

        public ThreadScheduler():this(new WorkQueue(),10) { }
        public ThreadScheduler(WorkQueue workQueue):this(workQueue,10){ }
        public ThreadScheduler(int concurrent) : this(new WorkQueue(),concurrent) { }
        public ThreadScheduler(WorkQueue workQueue,int concurrent)
        {
            _vWorkQueue = workQueue;
            _viConcurrentLimit = concurrent;
        }

        public void StartWork()
        {
            CheckAllFinished();

            while (_vWorkQueue.GetCount(WorkState.Ready) > 0)
            {
                System.Diagnostics.Trace.WriteLine(_vWorkQueue.GetCount(WorkState.Ready));
                if (_vWorkQueue.GetCount(WorkState.Running) < _viConcurrentLimit)
                {
                    IWork work = _vWorkQueue.GetWork();
                    work.State = WorkState.Running;
                    if (work != null)
                    {
                        System.Threading.Thread thread = new System.Threading.Thread(() => {
                            work.Perform();
                            work.State = WorkState.Completed;
                        });
                        thread.IsBackground = true;
                        thread.Start();
                    }
                }
            }
        }

    //这里要是用 一个volatile变量 来实现更准确的测试完成时间。不需要新起来一个线程啊!当然这个方法的调用位置需要修改。

        private void CheckAllFinished()
        {
            System.Threading.Thread thread = new System.Threading.Thread(() => {
                while (_vWorkQueue.GetCount(WorkState.Running) + _vWorkQueue.GetCount(WorkState.Ready) > 0)
                {
                    System.Threading.Thread.Sleep(50);
                }
                if (OnAllFinished != null)
                    OnAllFinished();
            });
            thread.IsBackground = true;
            thread.Start();
        }

    }

 测试类TestWork

public class TestWork : IWork
    {
        private string _vsName = string.Empty;
        private static int _viIndex = 1;
        private WorkState _vState = WorkState.Ready;

        public WorkState State
        {
            get { return _vState; }
            set { _vState = value; }
        }

        public TestWork() { }
        public TestWork(string name)
        {
            _vsName = name;
        }

        public void Perform()
        {
            Console.WriteLine(“{0}.{1}——–Thread:{2}”,_viIndex++,_vsName,System.Threading.Thread.CurrentThread.Name);
        }
    }

看看 效果:

class Program
    {
        static void Main(string[] args)
        {
            List<string> list = new List<string>();// new List<string>(new string[] { “Sunday”, “Monday”, “Tuesday”, “Wednesday” });

            #region Test One
            /*
            int count = 2;
            System.Threading.Thread[] threadArray = new System.Threading.Thread[count];
            for (int i = 0; i < count; i++)
            {
                threadArray[i] = new System.Threading.Thread(new TestWork(list[i]).Perform);
                threadArray[i].Name = string.Format(“WT#{0}”, i);
                threadArray[i].IsBackground = true;
            }

            foreach (System.Threading.Thread thread in threadArray)
            {
                thread.Start();
            }
            */
            #endregion

            Random random=new Random();
            for (int i = 0; i < 10000; i++)
            {
                list.Add(random.Next(10000).ToString());
            }

            DateTime startDateTime = DateTime.Now;
            Console.WriteLine(“There are {0} works as follows:”, list.Count);
            ThreadScheduler vThreadScheduler = new ThreadScheduler(8000);
            list.ForEach(item=>{
                vThreadScheduler.WorkQueue.Add(new TestWork(item));
            });
            vThreadScheduler.OnAllFinished += () =>
            {
                DateTime endDateTime=DateTime.Now;
                Console.WriteLine(“Works:{3},Used Time={0} <— {1}-{2}”,
                        endDateTime-startDateTime,endDateTime.ToString(),
                        startDateTime.ToString(),
                        vThreadScheduler.ConcurrentLimit
                    );
            };
            vThreadScheduler.StartWork();

            Console.WriteLine(“Over”);
            Console.Read();
        }
    }

测试发现当thread数量为任务数量一半的时候比80%要 快,比100%更快。当然这里的任务是小任务。

 源码下载

发表回复