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