多线程随笔

一、前言

  很久没有更新blog了,太忙了,都没时间来整理一下知识点,年底了有点时间了,可以好好整理以前写的项目代码了,顺便把常用的业务方法都封装成通用的方法,以便以后使用到能快速完成。切入主题,封装了一个常用的多线程使用场景的类库,提供两种模式,跟大家分享。

二、并发模式

  很多时候,我们会遇到这种情况,事件A和事件B毫无关系,是两个很耗时的相对独立事件,但是事件C需要用到事件A、B完成之后的结果。如下图,假设,我们的目的是建造一栋房子,事件A表示去拉砖头,事件B表示去找工人,事件C表示开始建房,

 

步骤代码片段:

static void Main(string[] args)
        {
            ThreadWRR.Init(ThreadWRR.RunningType.Concurrent);
            ThreadWRR.AddTask(Test1, "A");
            ThreadWRR.AddTask(Test2, "B");
            //ThreadWRR.AddTask(Test3, null);
            ThreadWRR.Start();
            
            while (ThreadWRR.IsRunning)
            {
                Console.WriteLine("C:在A、B完成之前,可以干一些活...");
            }
            Console.WriteLine("C:那开始建房吧!!!");
            Console.ReadKey();
        }

        static void Test1(object s)
        {
            Console.WriteLine(s + "正在去搬砖...");
            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine(s.ToString() +" 运送"+ i+"车...");
                Thread.Sleep(500);
            }
            Console.WriteLine(s + "搬完砖了!");
        }

        static void Test2(object s)
        {
            Console.WriteLine(s + "正在去找工人...");
            int ipeople = 0;
            for (int i = 1; i <= 5; i++)
            {
                ipeople += i * 5;
                Console.WriteLine(s.ToString() + " 找到" + ipeople + "个工人...");
                Thread.Sleep(500);
            }
            Console.WriteLine(s + "找够人了!");
        }

  

二、顺序模式

  另一种情况,事件B必须等事件A的结果,才能进行下一步任务的进行,C则等待AB都完成之后开始下一步任务,如图,假设,事件A表示组装电脑,事件B表示等A组装好之后进行打包工作,事件C表示装车去配送,C在AB过程中可以做一些事件,比如去拿车,去加油等等,总之do something。

步骤代码片段:

static void Main(string[] args)
        {
            ThreadWRR.Init(ThreadWRR.RunningType.Order);
            ThreadWRR.AddTask(Test1, "A");
            ThreadWRR.AddTask(Test2, "B");
            //ThreadWRR.AddTask(Test3, null);
            ThreadWRR.Start();
            
            while (ThreadWRR.IsRunning)
            {
                //Console.WriteLine("C:去加油");
            }
            Console.WriteLine("C:全部完毕,开始装车咯");
            Console.ReadKey();
        }

        static void Test1(object s)
        {
            Console.WriteLine(s + "正在组装...");
            for (int i = 0; i < 5; i++)
            {
                Thread.Sleep(500);
            }
            Console.WriteLine(s + "组装完成!");
        }

        static void Test2(object s)
        {
            Console.WriteLine(s + "正在打包...");
            for (int i = 0; i < 5; i++)
            {
              
                Thread.Sleep(500);
            }
            Console.WriteLine(s + "打包完成!");
        }

  咋一看是A组装一台,B打包一台才是,这里不是只有一台电脑而已嘛?!我认为两个事件已经在不同的线程上,需要相关业务逻辑去控制的,应该是我们去控制,不应该影响线程内部,才是符合OOA的开闭原则,当然,开发中比这复杂的业务还很多,不一定能应景。欢迎探讨~~

ThreadWRR类库代码:

 public sealed class ThreadWRR
    {
        private readonly static object objLock = new object();

        private static bool isRunning = false;
        private static RunningType runningType = RunningType.Order;
        private static List<Thread> lsThread = null;
        private static List<MethodParameter> listTask = null;
        /// <summary>
        /// 线程是否正在运行
        /// </summary>
        public static bool IsRunning
        {
            get
            {
                Thread.Sleep(1000);
                if (runningType == RunningType.Order)
                {
                    return isRunning;
                }
                else
                {
                    if (lsThread != null && lsThread.Count > 0)
                    {
                        int iFinish = 0;
                        lsThread.ForEach((th) =>
                        {
                            if (th.ThreadState == ThreadState.Stopped)
                            {
                                iFinish++;
                            }
                        });
                        return iFinish != lsThread.Count;
                    }
                    return false;
                }
            }
        }

        /// <summary>
        /// 等待所有线程
        /// </summary>
        public static void WaitAllTask()
        {
            while (IsRunning)
            {
            }
        }

        /// <summary>
        /// 初始化线程
        /// </summary>
        /// <param name="runType">运行方式</param>
        public static void Init(RunningType runType)
        {
            listTask = new List<MethodParameter>();
            lsThread = new List<Thread>();
            isRunning = false;
            runningType = runType;
        }

        /// <summary>
        ///  添加运行方法
        /// </summary>
        /// <param name="title"></param>
        /// <param name="method">方法名</param>
        /// <param name="parameter">方法参数</param>
        public static void AddTask(string title, FuncDelegateWithPara method, object parameter)
        {
            listTask.Add(new MethodParameter(title, method, parameter));
        }
       
        /// <summary>
        /// 添加运行方法
        /// </summary>
        /// <param name="title"></param>
        /// <param name="method">方法名</param>
        public static void AddTask(string title, FuncDelegate method)
        {
            listTask.Add(new MethodParameter(title, method));
        }

        /// <summary>
        /// 开始运行
        /// </summary>
        public static void Start()
        {
            if (!isRunning)
            {
                lock (objLock)
                {
                    if (!isRunning)
                    {
                        isRunning = true;
                        new Thread(() =>
                        {
                            switch (runningType)
                            {
                                case RunningType.Order:
                                    OrderTask();
                                    break;
                                case RunningType.Concurrent:
                                    ConcurrentTask();
                                    break;
                            }
                        }) { IsBackground = true }.Start();
                    }
                }
            }
        }

        private static void OrderTask()
        {
            foreach (MethodParameter funcObj in listTask)
            {
                IAsyncResult ia = null;
                if (funcObj.FuncWithPara == null)
                {
                    ia = BeginInvoke(funcObj.Func);
                }
                else
                {
                    ia = BeginInvoke(funcObj.FuncWithPara,funcObj.Parameter);
                }
                while (!ia.IsCompleted)
                {
                    Thread.Sleep(500);
                }
            }
            isRunning = false;
        }

        private static void ConcurrentTask()
        {
            foreach (MethodParameter funcObj in listTask)
            {
                Thread thread = null;
                if (funcObj.FuncWithPara == null)
                {
                    thread = new Thread(new ThreadStart(funcObj.Func)) { IsBackground = true };
                    thread.Start();
                }
                else
                {
                    thread = new Thread(new ParameterizedThreadStart(funcObj.FuncWithPara)) { IsBackground = true };
                    thread.Start(funcObj.Parameter);
                }
                lsThread.Add(thread);
            }
        }


        #region BeginInvoke / Invoke

        public static void Invoke(FuncDelegate func)
        {
            func.Invoke();
        }

        public static void Invoke(FuncDelegateWithPara func, object para)
        {
            func.Invoke(para);
        }

        public static IAsyncResult BeginInvoke(FuncDelegate func)
        {
            return func.BeginInvoke(null, null);
        }

        public static IAsyncResult BeginInvoke(FuncDelegateWithPara func, object para)
        {
            return func.BeginInvoke(para, null, null);
        }

        public static void Invoke(System.Windows.Forms.Control owner, FuncDelegate func)
        {
            if (owner.InvokeRequired)
            {
                owner.Invoke(func);
            }
            else
            {
                func();
            }
        }

        public static void Invoke(System.Windows.Forms.Control owner, FuncDelegateWithPara func, object para)
        {
            if (owner.InvokeRequired)
            {
                owner.Invoke(func, para);
            }
            else
            {
                func(para);
            }
        } 
        #endregion

        private class MethodParameter
        {
            public FuncDelegate Func = null;
            public FuncDelegateWithPara FuncWithPara = null;
            public object Parameter = null;
            public string title = "";

            public MethodParameter(string title, FuncDelegate func)
            {
                this.title = title;
                this.Func = func;
            }
            public MethodParameter(string title, FuncDelegateWithPara func, object para)
            {
                this.title = title;
                this.FuncWithPara = func;
                this.Parameter = para;
            }
        }
    }

    public delegate void FuncDelegateWithPara(object parameter);
    public delegate void FuncDelegate();


    /// <summary>
    /// 运行方式
    /// </summary>
    public enum RunningType
    {
        /// <summary>
        /// 顺序运行
        /// </summary>
        Order = 0x01,

        /// <summary>
        /// 并发运行
        /// </summary>
        Concurrent = 0x02
    }
View Code

 

posted @ 2016-11-30 15:16  山治先生  阅读(624)  评论(0编辑  收藏  举报