thread:线程等待,回调

    //1 thread:线程等待,回调,前台线程/后台线程
    //2 threadpool:线程池使用,设置线程池,ManualResetEvent
    //3 扩展封装thread&threadpool回调/等待
    class Program
    {
        static void Main(string[] args)
        {
            //ThreadTest threadTest = new ThreadTest();
            //threadTest.ThreadShow();
            ThreadPoolTest threadPoolTest = new ThreadPoolTest();
            threadPoolTest.ThreadPoolShow();

            Console.ReadLine();
        }

    }
    /// 多线程1.0
    /// Thread:C#对线程对象的一个封装
    public class ThreadTest
    {
        public void ThreadShow()
        {
            Console.WriteLine($"**************** Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");

            //{
            //    //执行无参数的委托
            //    ThreadStart method = () =>
            //    {
            //        DoSomething.DoSomethingLong("张三");
            //    };
            //    Thread thread = new Thread(method);
            //    thread.Start(); ;//开启线程,执行委托的内容          

            //    //thread.Suspend(); //已启用,暂停线程 
            //    //thread.Resume();  //已弃用,恢复线程
            //    //thread.Abort();   //停止线程 线程是计算机资源,程序想停下线程,只能向操作系统通知(线程抛异常),会有延时/不一定能真的停下来

            //    //1.等待
            //    //while (thread.ThreadState != ThreadState.Stopped) //根据线程状态判断
            //    //{
            //    //    Thread.Sleep(200);//当前线程休息200ms
            //    //}
            //    //2.Join等待
            //    //thread.Join();
            //    //thread.Join(1000);//最多等待1000ms
            //    //Console.WriteLine("线程完成之后的操作");

            //    //thread.Priority = ThreadPriority.Highest;
            //    //最高优先级:优先执行,但不代表优先完成  甚至说极端情况下,还有意外发生,不能通过这个来控制线程的执行先后顺序

            //    //    thread.IsBackground = false;//默认是false 前台线程,进程关闭,线程需要计算完后才退出
            //    //    thread.IsBackground = true;//关闭进程,线程退出
            //}

            //{
            //    //执行带参数的委托
            //    ParameterizedThreadStart method = (o) =>
            //    {
            //        DoSomething.DoSomethingLong(o.ToString());
            //    };
            //    Thread thread = new Thread(method);
            //    thread.Start("张三"); ;//开启线程,执行委托的内容          
            //}

            //Action action = () =>
            //{
            //    Thread.Sleep(2000);
            //    Console.WriteLine("线程执行完回调方法");
            //};
            //ThreadStart method = () =>
            //{
            //    DoSomething.DoSomethingLong("张三");
            //};
            //this.ThreadWithCallBack(method, action);

            Func<int> method = () =>
            {
                Thread.Sleep(2000);
                return 123;
            };

            Func<int> funcThread = this.ThreadWithReturn(method);//非阻塞
            //Console.WriteLine("do something else/////");
            //Console.WriteLine("do something else/////");
            //Console.WriteLine("do something else/////");
            //Console.WriteLine("do something else/////");
            //Console.WriteLine("do something else/////");
            int iResult = funcThread.Invoke();//当获取值的时候会阻塞
            Console.WriteLine(iResult);

            Console.WriteLine($"**************** End {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");

        }

        //基于thread封装一个回调
        //回调:启动子线程执行动作A--不阻塞--A执行完后子线程会执行动作B
        /// <summary>
        /// 
        /// </summary>
        /// <param name="threadStart">多线程执行的操作</param>
        /// <param name="actionCallback">线程完成后,回调的动作</param>
        public void ThreadWithCallBack(ThreadStart threadStart, Action actionCallback)
        {
            ThreadStart start = new ThreadStart(() =>
            {
                threadStart.Invoke();
                actionCallback.Invoke();
            });
            new Thread(start).Start();
        }

        /// <summary>
        /// 1 异步,非阻塞的
        /// 2 还能获取到最终计算结果
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="func"></param>
        /// <returns></returns>
        private Func<T> ThreadWithReturn<T>(Func<T> func)
        {
            T t = default(T);
            ThreadStart start = new ThreadStart(() =>
            {
                t = func.Invoke();
            });
            Thread thread = new Thread(start);
            thread.Start();

            return new Func<T>(() =>
              {
                  thread.Join();
                  return t;
              });
        }

    }
  /// 
    /// 线程池.NetFramework2.0
    /// 如果某个对象创建和销毁代价比较高,同时这个对象还可以反复使用的,就需要一个池子
    /// 保存多个这样的对象,需要用的时候从池子里面获取;用完之后不用销毁,放回池子
    /// 节约资源提升性能;此外,还能管控总数量,防止滥用;
    /// 
    /// ThreadPool的线程都是后台线程
    /// 
    public class ThreadPoolTest
    {
        public void ThreadPoolShow()
        {
            //开启线程执行委托
            //ThreadPool.QueueUserWorkItem(o =>
            //{
            //    Console.WriteLine("123");
            //});


            //ThreadPool.GetMaxThreads(out int workerThreads, out int completionPortThreads);
            //Console.WriteLine($"当前电脑最大workerThreads={workerThreads} 最大completionPortThreads={completionPortThreads}");

            //ThreadPool.GetMinThreads(out int workerThreadsMin, out int completionPortThreadsMin);
            //Console.WriteLine($"当前电脑最小workerThreads={workerThreadsMin} 最大completionPortThreads={completionPortThreadsMin}");

            ////设置的线程池数量是进程全局的,
            ////委托异步调用--Task--Parrallel--async/await 全部都是线程池的线程
            ////直接new Thread不受这个数量限制的(但是会占用线程池的线程数量) 如果线程池数量已用完还是可以new Thread,如果先new Thread 会占用线程池数量
            //ThreadPool.SetMaxThreads(8, 8);//设置的最大值,必须大于CPU核数,否则设置无效
            //ThreadPool.SetMinThreads(2, 2);
            //Console.WriteLine("&&&&&&&&&&&&&&&&&&&&&&&设置最大最小&&&&&&&&&&&&&&&&&&&&&&&&&&&");

            //ThreadPool.GetMaxThreads(out int workerThreads1, out int completionPortThreads1);
            //Console.WriteLine($"当前电脑最大workerThreads={workerThreads1} 最大completionPortThreads={completionPortThreads1}");

            //ThreadPool.GetMinThreads(out int workerThreadsMin1, out int completionPortThreadsMin1);
            //Console.WriteLine($"当前电脑最大workerThreads={workerThreadsMin1} 最大completionPortThreads={completionPortThreadsMin1}");

            {
                //等待
                ManualResetEvent mre = new ManualResetEvent(false);
                //false---关闭---Set打开---true---WaitOne就能通过
                //true---打开--ReSet关闭---false--WaitOne就只能等待
                ThreadPool.QueueUserWorkItem(o =>
                {
                    DoSomething.DoSomethingLong("btnThreadPool_Click1");
                    mre.Set();
                });
                Console.WriteLine("Do Something else...");
                Console.WriteLine("Do Something else...");
                Console.WriteLine("Do Something else...");

                mre.WaitOne();
                Console.WriteLine("任务已经完成了。。。");
            }
        }

    }
posted @ 2020-01-06 16:13  王大师123  阅读(1045)  评论(0编辑  收藏  举报