C#多线程概叙
为什么要用多线程?在什么场景下使用?
1,为了提升效率,各个任务可以并发执行,各个任务可以分割,采用空间换时间的方式。
什么情况下不能使用多线程优化?
查询数据库的时候,不能使用多线程,因为这是一个不可分割的任务。
多线程的问题
使用多线程一时爽,但是爽的同时要注意身体,多线程会带来的问题。CPU调度的时间片是30ms
- 执行的无序性;
- 线程的不安全性;
- 尽量不要线程套线程,否则会套晕根还在线程的无序性;
- 子线程是不能操作UI控件
多线程的发展历史
Thread->Thread pool -> Task -> async await
async await 特性,是一个语法糖,不是一个全新的方式,依托于Task存在, async可以随便添加,可以不用await,如果要用await,必须要有async,并且只能出现在task签名,使得没有返回值的,可以返回一个task. 程序在执行到await的时候,此时主线程也开始执行,进入到并发
线程安全
线程安全主要发生在修改对象数据的时候发生。官方的解释是一段代码,单线程执行的结果和多线程执行的结果不一致,这就是线程安全
- 使用锁,主要lock, 微软官方的写法是 private static readonly object LOCK_OBJECT= new object();为什么要用私有,静态,只读的呢?因为锁只能锁一个引用类型,不能锁一个值类型,自己锁自己,最好不用公用,否则锁两个线程不能并发。锁的使用是异步线程变同步,在编译后使用的是Monitor.start() Monitor end(),其他为进入锁的线程只能在外面排队。还有一点要注意的,在线程内的异常,子线程会把异常吃掉,不会影响程序,所以要catch 子线程中的异常,try catch要加到内部
- 数据的一致性,线程安全主要发生在修改数据的时候发生,在读数据的时候,可以轻松避免,将每次的数据赋值到一个变量里面,这样确保每次输入的变量都是新的。此种方式主要是异步线程在循环内部使用。
static void Main(string[] args)
{
/故事是这样的,我打算带小朋友出去玩,在出去玩之前,我要给汽车加油,妈妈要收拾物品,小朋友要打游戏
* 为了尽快出去玩,我们同时做自己的事情,然后谁完成了自己的事情,就发个消息出来,最后全部完成后,大家一起出去玩
/
Console.WriteLine(“今天打算带小朋友出去玩!”);
List listTask = new List();
listTask.Add( Task.Run(() =>
{
Coding(“我”,“加油”);
}));
listTask.Add(Task.Run(()=> {
Coding(“妈妈”, “收拾物品”);
}));
listTask.Add(Task.Run(() =>
{
Coding(“小朋友”, “收拾物品”);
}));
TaskFactory taskFactory = new TaskFactory();
listTask.Add(taskFactory.ContinueWhenAny(listTask.ToArray(),task=> {
Console.WriteLine(KaTeX parse error: Expected 'EOF', got '}' at position 67: …); }̲)); …"{Thread.CurrentThread.ManagedThreadId} 全部完成了,再次检查下");
})
);
Task.WaitAny(listTask.ToArray()); // 阻塞当前主线程,直到任一一个完成,造成卡界面
Console.WriteLine("*,去倒水,准备出去");
Task.WaitAll(listTask.ToArray());
Console.WriteLine(“检查全部完成了,大家一起去玩”);
Console.ReadKey();
}
private static void Coding(string name,string task)
{
Console.WriteLine(name + “” + task);
}