//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("任务已经完成了。。。"); } } }