学习笔记——多线程

1、多线程优缺点

优:可以提高CPU的利用率。在多线程程序中,一个线程必须等待的时候,CPU可以运行其它的线程而不是等待,这样就大大提高了程序的效率。

缺:①线程也是程序,所以线程需要占用内存,线程越多占用内存也越多;CPU需要协调和管理多线程

    ②线程太多会导致控制太复杂,最终可能造成很多Bug

    ③对共享资源的访问会相互影响

    ④程序难调试

2、ThreadPool &Task

2.1. ThreadPool 2.0 出现的

去掉各种API,避免滥用,降低复杂度

池化:减少创建、销毁的成本;可以限制最大线程数量

2.2. Task 3.0 出现

使用的是线程池的线程  全部是后台线程

API很强大,调用简单

注意:尽量不要在Task里面启动Task

3、ThreadPool

3.1.实例:

ThreadPool.QueueUserWorkItem(

    o =>

    {

        new Action(() =>

        {

            Thread.Sleep(5000);

            this.DoSomethingLong("btnThreads_Click");

            //回调  就包一层,放在这里

        }).Invoke();

        //后续动作

        Console.WriteLine("1234356786954");

    });

 

3.2.线程池等待

//ManualResetEvent(false)   false:mre.WaitOne()不执行,set()后可执行

ManualResetEvent mre = new ManualResetEvent(false);

ThreadPool.QueueUserWorkItem(o =>

{

    Thread.Sleep(5000);

    this.DoSomethingLong("btnThreads_Click");

    Console.WriteLine(o.ToString());

 

    //此处set()后mre.WaitOne()可以执行。

    mre.Set();

}, "backbone");

 

Console.WriteLine("before WaitOne");

mre.WaitOne();

Console.WriteLine("after WaitOne");

 

3.3.管理线程池数量

 //管理线程池的数量

 //ThreadPool.SetMaxThreads(8, 8);//最小也是核数

 //ThreadPool.SetMinThreads(8, 8);

 //下面一段查看自己电脑的线程池情况

 int workerThreads = 0;

 int ioThreads = 0;

 ThreadPool.GetMaxThreads(out workerThreads, out ioThreads);

 Console.WriteLine(String.Format("Max worker threads: {0};    Max I/O threads: {1}", workerThreads, ioThreads));

 

 ThreadPool.GetMinThreads(out workerThreads, out ioThreads);

 Console.WriteLine(String.Format("Min worker threads: {0};    Min I/O threads: {1}", workerThreads, ioThreads));

 

 ThreadPool.GetAvailableThreads(out workerThreads, out ioThreads);

 Console.WriteLine(String.Format("Available worker threads: {0};    Available I/O threads: {1}", workerThreads, ioThreads));

 

4、Task

4.1.实例

Task t1 = Task.Run(new Action(() =>

        {

            Thread.Sleep(5000);

            this.DoSomethingLong("btnTask_Click");

        }));

 

4.2.多线程常用方法

TaskFactory taskFactory = Task.Factory;// new TaskFactory();

List<Task> taskList = new List<Task>();

taskList.Add(taskFactory.StartNew(() => this.DoSomethingLong("btnTask_Click_0")));

taskList.Add(taskFactory.StartNew(() => this.DoSomethingLong("btnTask_Click_1")));

 

//回调(不会卡界面)

taskList.Add(taskFactory.ContinueWhenAny(taskList.ToArray(), t => Console.WriteLine($"ContinueWhenAny {Thread.CurrentThread.ManagedThreadId.ToString("00")}")));

taskList.Add(taskFactory.ContinueWhenAll(taskList.ToArray(), tList => Console.WriteLine($"这里是ContinueWhenAll {Thread.CurrentThread.ManagedThreadId.ToString("00")}")));

 

//多业务操作  并发,,但是某个完成后,就返回

Task.WaitAny(taskList.ToArray());//卡界面

Console.WriteLine("某个任务完成,才会执行");

 

//多业务操作  并发,,但是全部完成后,才能返回

Task.WaitAll(taskList.ToArray());//卡界面(主线程在等待)

Console.WriteLine("全部任务都完成,才会执行");

 

//多线程并发,某一个线程完成进行的操作(示例)

Task task = taskFactory.StartNew(t => this.DoSomethingLong("btnTask_Click_005"), "测试参数")

                      .ContinueWith(t => Console.WriteLine($"这里是{t.AsyncState}的回调"));

 

Task<int> intTask = taskFactory.StartNew(() => 123);

int iResult = intTask.Result;

 

参考资料 https://blog.csdn.net/qq_36598803/article/details/77645651

posted @ 2018-12-03 17:53  鲁燕云端  阅读(132)  评论(0编辑  收藏  举报