• C#线程发展历史


    有严格时间、先后顺序限制的只能使用单线程;可以独立并发执行的就可以使用多线程

    一、Thread(.NetFramework 1.0)

    优点:API丰富,可执行的操作多

    缺点:1、Thread线程虽然可执行的操作多,但是响应并不灵敏(因为具体的线程分配要CPU决定),所以可能达不到想要的效果。

               2、Thread线程启动是没有控制的(如果实例化了一百万个线程是真的会调用一百万个线程),所以可能会导致死机。

    1. Thread thread = new Thread((a) => { Console.WriteLine("asdf"+a); });
    2. thread.Start(6);

    常用api

    1. 开启一个新线程
    2. thread.Start();
    3. 线程挂起,已经过期的方法
    4. //thread.Suspend();
    5. //thread.Resume();//线程恢复,已经过期的方法
    6. 终结线程,抛出一个异常
    7. thread.Abort();
    8. 把终结的线程再次启动,会有延时
    9. Thread.ResetAbort();
    10. 设置优先级,不能保证一定会优先执行,只是提升概率
    11. thread.Priority = ThreadPriority.Highest;
    12. 为后台线程,线程随进程结束而结束
    13. thread.IsBackground = true;
    14. 前台线程,进程结束后,任务执行完毕以后线程才结束
    15. thread.IsBackground = false;
    16. 线程等待
    17. 1 ThreadState判断
    18. while (thread.ThreadState!=ThreadState.Stopped)
    19. {
    20. Thread.Sleep(200);
    21. }
    22. 2 Join等待
    23. thread.Join();//等待线程结束
    24. thread.Join(200);//限时等待,最多等待200ms,超时就不等了

    二、ThreadPool (.NetFrameWork 2.0)

    优点:使用池化资源管理设计思想。线程是一种资源,要使用线程就去申请一个线程,使用之后就释放掉;池化就是做了一个容器,容器提前申请线程,程序要使用线程就直接找容器获取,用完再放回容器,避免频繁的申请和销毁;容器自己还会根据限制的数量去申请和释放。

    缺点:API太少了,在线程等待顺序控制特别弱(MRE解决)

    1. WaitCallback callback1 = o => { Console.WriteLine("dfhj"); }; //不带参数
    2. ThreadPool.QueueUserWorkItem(callback1);
    3. WaitCallback callback2 = o => { Console.WriteLine("dfhj"+o); };//带参数
    4. ThreadPool.QueueUserWorkItem(callback2,"wh");

    线程池常用API

    三、Task(.NetFramework 3.0)多线程的最佳实践

    优点:1、使用了线程池的

               2、API特别多

    task.start()

    1. Action action = () => { Console.WriteLine("hello,world"); };
    2. Task task = new Task(action);
    3. task.Start();

    task.run()

    带参

    1. tasks.Add(Task.Run(()=> { Test("hello,word"); })); //带参
    2. //委托调用的函数
    3. public void Test(string i)
    4. {
    5. Thread.Sleep(5000);
    6. Console.WriteLine(i);
    7. }

    无参

    1. tasks.Add(Task.Run(()=> { Test(); })); //带参
    2. //委托调用的函数
    3. public void Test()
    4. {
    5. Thread.Sleep(5000);
    6. Console.WriteLine("hello word");
    7. }

    Task.WaitAll      此方法需要传进一个线程数组。数组里的线程执行过程中,会阻塞主线程。

    Task.WaitAny    当数组中的任意一个线程完成后就会继续往下执行     

    1. Console.WriteLine("主线程");
    2. List tasks = new List();
    3. tasks.Add(Task.Run(()=> { Test(1); }));
    4. tasks.Add(Task.Run(() => { Test(2); }));
    5. tasks.Add(Task.Run(() => { Test(3); }));
    6. tasks.Add(Task.Run(() => { Test(4); }));
    7. tasks.Add(Task.Run(() => { Test(5); }));
    8. Task.WaitAny(tasks.ToArray());
    9. Console.WriteLine("程序1/5");
    10. Task.WaitAll(tasks.ToArray());
    11. Console.WriteLine("程序完成");

    但是当阻塞线程的时候,主线程会卡住。为了避免主线程卡住,可以选择用TaskFactory.ContinueWhenAll的方式解决(括号里第一个参数是要执行的线程数组,第二个参数是执行完线程数组之后要执行函数的委托(类似与BeginInvoke的第二个参数))

    1. List tasks = new List();
    2. tasks.Add(Task.Run(()=> { Test(1); }));
    3. tasks.Add(Task.Run(() => { Test2(2); }));
    4. tasks.Add(Task.Run(() => { Test(3); }));
    5. tasks.Add(Task.Run(() => { Test(4); }));
    6. tasks.Add(Task.Run(() => { Test(5); }));
    7. TaskFactory taskFactory = new TaskFactory();
    8. taskFactory.ContinueWhenAny(tasks.ToArray(), tArray => { Console.WriteLine("程序完成1/5"); });
    9. taskFactory.ContinueWhenAll(tasks.ToArray(), tArray => { Console.WriteLine("程序完成"); });

    四、Parallel(并行编程)

    Parallel可以启动多线程,但是主线程也参与计算(其他异步线程调用时候主线程闲着啥也不干,使用Parallel主线程也产于计算所以可以少申请一个线程),故卡界面。

    1. Parallel.Invoke(
    2. () => { Thread.Sleep(2000); Console.WriteLine("hello,world1"); },
    3. () => { Thread.Sleep(2000); Console.WriteLine("hello,world2"); },
    4. () => { Thread.Sleep(2000); Console.WriteLine("hello,world3"); },
    5. () => { Thread.Sleep(2000); Console.WriteLine("hello,world4"); }
    6. );

    可以通过ParallelOption轻松控制最大并发数量。

  • 相关阅读:
    【LeetCode】79. 单词搜索
    【Python自动化】定时自动采集,并发送微信告警通知,全流程案例讲解!
    Redis
    【Cherno的OpenGL视频】Creating tests in OpenGL
    经典算法之希尔排序
    MFC中不同编码格式内容的写入
    细胞穿膜肽TAT/血管肽Angiopep/靶向多肽cRGD偶联TIO2二氧化钛纳米粒(TiO2-Angiopep)
    【C语言】 01.C语言常见概念
    .net----委托和事件
    vue3 defineProps 函数
  • 原文地址:https://blog.csdn.net/m0_60939437/article/details/126519784