C#中的线程
---恢复内容开始---
进程和线程的关系:
进程中包括线程(在任务管理器中可以查看)
线程之间可以共享数据。()
创建线程的方法1(不带返回值):
//创建一个线程 var task1 = new Task( ()=>//线程中执行的内容,无返回值时直接用函数名即可 { for (int i = 0; i < 500; i++) { Console.WriteLine("--"); } }//实例化的Task 是一个委托、引用,不能立即执行,需要Start方法才能执行 ); //创建另一个线程 var task2 = new Task(()=> { for (int i = 0; i < 500; i++) { Console.WriteLine("!!!"); } }); //同时启动线程 task1.Start(); task2.Start(); //同时等待线程(阻塞效果) task1.Wait(); task2.Wait(); }
创建线程的方法2(带返回值):
//创建一个线程 var task = Task.Factory.StartNew(()=>"1");//可以直接执行,不需要Start Console.WriteLine( task.Result);//阻塞效果
线程上的异常处理(catch Aggery异常)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
var task = Task.Factory.StartNew(()=> { throw new ApplicationException("有异常");//执行该语句 });//可以直接执行,不需要Start try { task.Start(); task.Wait(); } catch (AggregateException e)//捕获异常 { foreach (var item in e.InnerExceptions) { Console.WriteLine(item); } }
线程的异常处理(Task.ContinueWith(执行语句,执行的条件)
/创建一个线程 var task = Task.Factory.StartNew(()=> { throw new ApplicationException("有异常");//执行该语句 });//可以直接执行,不需要Start task.ContinueWith((t)=> { Console.Write("11111"); },TaskContinuationOptions.OnlyOnFaulted);//t上一个线程(执行语句,执行的条件)
线程的线性执行(按照顺序)
var ts = new List<int>();//定义一个list,名称为ts,元素为int类型 for (int i = 0; i < 500000; i++) { //利用ADD方法添加数据到List ts.Add(i); } //利用秒表计算运行的时间 Stopwatch stopwatch = new Stopwatch();//实例化StopWatch stopwatch.Start();//开始秒表 //被计时的程序 ts.ForEach(i=>i++);//遍历,(action=>{执行语句}) stopwatch.Stop();//停止 Console.WriteLine(stopwatch.ElapsedMilliseconds);//输出时间设
涉及封装技巧(构造方法、模块、套公式)Action封装一个方法,访问()=>{执行的语句}
static long Time( Action action)//返回值时间long类型 { Stopwatch stopwatch = new Stopwatch();//实例化StopWatch stopwatch.Start();//开始秒表 //被计时的程序 //ts.ForEach(i => i++);//遍历,(action=>{执行语句}) action(); stopwatch.Stop();//停止 return stopwatch.ElapsedMilliseconds;//long类型 }
Time(() => {ts.ForEach(i => i++);});//调用封装的方法(i=>操作):对i元素的操作
并行处理:处理的数据越复杂,并行效果越好。
static void Main(string[] args)//主线程,可以启动其他线程 { //定义一个list,名称为ts,元素为int类型 var ts = new List<int>(); //利用ADD方法for循环添加数据到List for (int i = 0; i < 5000000; i++) { ts.Add(i); } Time(() =>{ ts.ForEach(i =>Math.Cos( Math.Abs( Math.Sin(i)))); });//调用封装的方法,对list中的每一个i进行i++ //i=>{对i的操作,可以包装为函数,ref int i} Time(()=> { ts.AsParallel().ForAll(i =>Math.Cos( Math.Abs(Math.Sin(i)))); });//调用方法,对list中的每一个i进行并行方式的i++ Time(() => { Parallel.ForEach(ts, i++); }); Console.Read(); }
线程的同步(原子性,一致性)
//创建两个线程,//设置执行的语句 //()=>{执行的语句} Task task1 = new Task(()=> { for (int i = 0; i < 900000000; i++) { count++; } }); //静态方法action直接用函数名 Task task2 = new Task(Math); task1.Start();//启动线程 task2.Start(); Task.WaitAll(); Console.WriteLine(count);//线程之间会随机切换
利用Lock关键字保护线程 (利用 “锁”)
private static readonly object Syn = new object();//声明变量 static void Math( ) { for (int i = 0; i < 900000000; i++) { lock (Syn)//利用Lock关键字 保护线程不切换 { count--; } } }
多个线程访问同一个对象时,未来防止混乱,需要Lock
---恢复内容结束---