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("任務已經完成了。。。");
            }
        }

    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM