异步和多线程,委托异步调用,Thread,ThreadPool,Task,Parallel,CancellationTokenSource
1 进程-线程-多线程,同步和异步
2 异步使用和回调
3 异步参数
4 异步等待
5 异步返回值
5 多线程的特点:不卡主线程、速度快、无序性
7 thread:线程等待,回调,前台线程/后台线程,
8 threadpool:线程池使用,设置线程池,ManualResetEvent
9 Task初步接触
10 task:waitall waitany continueWhenAny continueWhenAll
11并行运算Parallel
12 异常处理、线程取消、多线程的临时变量和lock
13 Await/Async
- Anker_张(博客园)http://www.cnblogs.com/AnkerZhang/
- //简单同步委托、方法调用 val是返回值
- Func<int, string> func1 = i =>
- {
- string result = i + "变返回值";
- return result;
- };
- string val= func1.Invoke();
- //委托、方法异步调用
- func1.BeginInvoke(, null, null);//开启新的进程去执行方法
- IAsyncResult asyncResult = null;//表示异步操作的状态。
- AsyncCallback callback = t => //回调函数方法处理
- {
- Console.WriteLine(t.Equals(asyncResult));//运行起来是true
- Console.WriteLine(t.AsyncState);//t.AsyncState回调函数所需要传的参数
- Console.WriteLine("这里是回调函数 {0}", Thread.CurrentThread.ManagedThreadId);//表示线程ID
- };
- asyncResult = func1.BeginInvoke(, callback, "我是回调函数参数");//参数1:委托所需int参数,2:穿入回调函数,3:回调函数参数,返回值是回调函数
- bool b = asyncResult.IsCompleted;//指示异步操作是否已完成。 返回结果: 如果操作完成则为 true,否则为 false。
- asyncResult.AsyncWaitHandle.WaitOne();//一直等待
- asyncResult.AsyncWaitHandle.WaitOne(-);//一直等待
- asyncResult.AsyncWaitHandle.WaitOne();//等待1000毫秒,超时就不等待了
- func1.EndInvoke(asyncResult);//会一直等待回调函数执行完成
委托的异步调用
异步多线程的三大特点:
1 同步方法卡界面,原因是主线程被占用;异步方法不卡界面,原因是计算交给了别的线程,主线程空闲
2 同步方法慢,原因是只有一个线程计算;异步方法快,原因是多个线程同时计算,但是更消耗资源,不宜太多
3 异步多线程是无序的,启动顺序不确定、执行时间不确定、结束时间不确定
- /// <summary>
- /// 执行动作:耗时而已
- /// </summary>
- private static void TestThread(string threadName)
- {
- Console.WriteLine("TestThread Start Name={2}当前线程的id:{0},当前时间为{1},", System.Threading.Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"), threadName);
- long sum = ;
- for (int i = ; i < ; i++)
- {
- sum += i;
- }
- Console.WriteLine("TestThread End Name={2}当前线程的id:{0},当前时间为{1},计算结果{3}", System.Threading.Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"), threadName, sum);
- }
- //多线程
- Stopwatch watch = new Stopwatch();//用于计时器
- watch.Start();//开始计时
- Console.WriteLine();
- Console.WriteLine("***********************btnThread_Click Start 主线程id {0}**********************************", Thread.CurrentThread.ManagedThreadId);
- List<Thread> threadList = new List<Thread>();
- for (int i = ; i < ; i++)
- {
- string name = string.Format("btnThread_Click_{0}", i);
- ThreadStart method = () => TestThread(name);
- Thread thread = new Thread(method);//1 默认前台线程:程序退出后,计算任务会继续
- thread.IsBackground = true;//2 后台线程:程序退出,计算立即结束
- thread.Start();//启动线程
- threadList.Add(thread);//添加在集合
- }
- foreach (Thread thread in threadList)
- {
- thread.Join();///等待每个线程执行完毕
- }
- watch.Stop();//结束计算时间
- Console.WriteLine("**********************btnThread_Click End 主线程id {0} {1}************************************", Thread.CurrentThread.ManagedThreadId, watch.ElapsedMilliseconds);
- Console.WriteLine();
线程池(ThreadPool)
可设置线程池线程数量,把线程留在程序中
每次可循环使用,不用再去和操作系统申请线程
- //线程池
- ManualResetEvent mre = new ManualResetEvent(false);
- for (int i = ; i < ; i++)
- {
- string name = string.Format("ThreadPool{0}", i);
- WaitCallback method = t => {
- Console.WriteLine("我是异步调用方法参数:{0}", t.ToString());
- mre.Set(); //打开 mre.Reset();//关闭
- };
- ThreadPool.QueueUserWorkItem(method, name);
- }
- Console.WriteLine("我们来干点别的。。。。");
- Console.WriteLine("我们来干点别的。。。。");
- Console.WriteLine("我们来干点别的。。。。");
- Console.WriteLine("我们来干点别的。。。。");
- mre.WaitOne();//判断线程是否全部执行完成
- ThreadPool.SetMaxThreads(, );//设置最大线程池数量和IO线程池运行数量
- ThreadPool.SetMinThreads(, );
- int workerThreads;
- int ioThreads;
- ThreadPool.GetMaxThreads(out workerThreads, out ioThreads);//获取当前线程状况
Task
CRL4.0
引用 Task是基于线程池开发,效率提升
- //Task CRL4.0引用 Task是基于线程池开发,效率提升
- {
- TaskFactory taskFactory = new TaskFactory();//创建Task工厂
- for (int i = ; i < ; i++)
- {
- string name = string.Format("Async_{0}", i);
- Action act = () => TestThread(name);//这个方法执行动作:耗时而已
- Task task = taskFactory.StartNew(act);//这里也可以 Task task =new Task(act);
- task.Start();//启动Task
- }
- }
- //Task一下方法比较效率高推荐使用
- {
- TaskFactory taskFactory = new TaskFactory();//创建Task工厂
- List<Task> taskList = new List<Task>();//创建Task集合
- Action<object> act = o => Console.WriteLine(o.ToString());
- Task task = taskFactory.StartNew(act, "参数1");//创建一个新的委托Task方法
- taskList.Add(task);
- taskList.Add( taskFactory.StartNew(s => Console.WriteLine(s.ToString()), "参数2"));
- Task any = taskFactory.ContinueWhenAny(taskList.ToArray(), t =>//taskList中任意任务线程执行完毕,就执行该方法(异步执行)
- {
- //t.AsyncState
- Console.WriteLine("这里是ContinueWhenAny {0}", Thread.CurrentThread.ManagedThreadId);//打印线程ID
- });
- Task all = taskFactory.ContinueWhenAll(taskList.ToArray(), tList =>//taskList中全部任务线程执行完毕,就执行该方法(异步执行)
- {
- Console.WriteLine("这里是ContinueWhenAll {0}", Thread.CurrentThread.ManagedThreadId);
- });
- Task.WaitAny(taskList.ToArray());//执行的线程等待某一个task的完成
- Task.WaitAll(taskList.ToArray());//执行的线程等待全部的task的完成
- }
Parallel 并行计算
Parallel是基于Task开发,并行计算与Task.WaitAll执行等待结果不同的是:Task.WaitAll在执行时主线程在锁死等在子线程执行完成
Parallel是主线程也同样随机分配一个子线程去执行任务,Parallel比Task少开启一个线程
- //Parallel 并行计算
- Parallel.Invoke(() => TestThread("btnParallel_Click_0")//这个方法执行动作:耗时而已
- , () => TestThread("btnParallel_Click_1")//这个方法执行动作:耗时而已
- , () => TestThread("btnParallel_Click_2")//这个方法执行动作:耗时而已
- , () => TestThread("btnParallel_Click_3")//这个方法执行动作:耗时而已
- , () => TestThread("btnParallel_Click_4"));//这个方法执行动作:耗时而已
- //等于使用4个task,然后主线程同步invoke一个委托 然后主线程waitall
- Parallel.For(, , t =>
- {
- string name = string.Format("For btnParallel_Click_{0}", t);
- TestThread(name);//这个方法执行动作:耗时而已
- });
- ParallelOptions parallelOptions = new ParallelOptions()
- {
- MaxDegreeOfParallelism = //实例所允许的最大并行度。
- };
- Parallel.For(, , parallelOptions, (t, state) =>
- {
- string name = string.Format("btnParallel_Click_{0}", t);
- TestThread(name);
- state.Break();//退出单次循环
- state.Stop();//退出全部的循环
- return;
- });
异常处理、线程取消、多线程的临时变量和线程安全lock
- //异常处理、线程取消、多线程的临时变量和线程安全lock
- CancellationTokenSource cts = new CancellationTokenSource();//线程取消专用实例
- TaskFactory taskFactory = new TaskFactory();
- List<Task> taskList = new List<Task>();
- for (int i = ; i < ; i++)
- {
- Action<object> act = t =>
- {
- try
- {
- if (t.ToString().Equals(""))//模拟当i=10抛异常
- {
- throw new Exception(string.Format("{0} 执行失败", t));
- }
- if (!cts.IsCancellationRequested)//是否被取消
- {
- Console.WriteLine("{0} 执行成功", t);
- }
- else
- {
- Console.WriteLine("{0} 被取消", t);
- }
- }
- catch (Exception ex)
- {
- cts.Cancel();// 传达取消请求。
- Console.WriteLine("子线程异常 {0}", ex.Message);
- }
- };
- taskFactory.StartNew(act, i);
- Task task = taskFactory.StartNew(act, i, cts.Token);//加上 cts.Token 如果被取消集合里面剩余的线程就不会启动了
- taskList.Add(task);
- }
- Task.WaitAll(taskList.ToArray());
- ///多线程的临时变量和线程安全lock
- ///每次实例新对象防止变量访问冲突
- ///如果同时访问同一变量加上Lock
- ///private static object obj = new object();
- ///lock (obj)
- ///{
- /// 锁住啦
- ///}
异步和多线程,委托异步调用,Thread,ThreadPool,Task,Parallel,CancellationTokenSource的更多相关文章
- c#中@标志的作用 C#通过序列化实现深表复制 细说并发编程-TPL 大数据量下DataTable To List效率对比 【转载】C#工具类:实现文件操作File的工具类 异步多线程 Async .net 多线程 Thread ThreadPool Task .Net 反射学习
c#中@标志的作用 参考微软官方文档-特殊字符@,地址 https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/toke ...
- 从Thread,ThreadPool,Task, 到async await 的基本使用方法解读
记得很久以前的一个面试场景: 面试官:说说你对JavaScript闭包的理解吧? 我:嗯,平时都是前端工程师在写JS,我们一般只管写后端代码. 面试官:你是后端程序员啊,好吧,那问问你多线程编程的问题 ...
- Thread,ThreadPool,Task, 到async await 的基本使用方法和理解
很久以前的一个面试场景: 面试官:说说你对JavaScript闭包的理解吧? 我:嗯,平时都是前端工程师在写JS,我们一般只管写后端代码. 面试官:你是后端程序员啊,好吧,那问问你多线程编程的问题吧. ...
- 异步多线程 Thread ThreadPool Task
一.线程 Thread ThreadPool 线程是Windows任务调度的最小单位,线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针.程序计数器等),但代码区是共享的,即不同的线程可以 ...
- .NET多线程(Thread,ThreadPool,Task,Async与Await)
.NET多线程是什么? 进程与线程 进程是一种正在执行的程序. 线程是程序中的一个执行流. 多线程是指一个程序中可以同时运行多个不同的线程来执行不同的任务. .NET中的线程 Thread是创建和控制 ...
- .net 多线程 Thread ThreadPool Task
先准备一个耗时方法 /// <summary>/// 耗时方法/// </summary>/// <param name="name">< ...
- Thread,ThreadPool,Task
线程分为前台和后台.比如我们直接new一个Thread这就是前台线程. 前台线程一定会执行. 比如我们创建2个线程:1号,2号,同时执行,假设1号是主线程,1执行完了,依旧会等待2执行完成,整个程序才 ...
- Thread&ThreadPool、Parallel、Async和Await用法总结
1.线程和线程池Thread&ThreadPool //线程初始化时执行方法可以带一个object参数,为了传入自定义参数,所以执行需单独调用用于传参. Console.WriteLine(& ...
- 浅析C#中的Thread ThreadPool Task和async/await
.net 项目中不可避免地要与线程打交道,目的都是实现异步.并发.从最开始的new Thread()入门,到后来的Task.Run(),如今在使用async/await的时候却有很多疑问. 先来看一段 ...
随机推荐
- Struts2问题总结
1 如何搭建Struts2开发环境? Struts2 获取 http://struts.apache.org/download.cgi Struts-2.3.16.3-all.zip 创建Web项 ...
- 【题解】P2602[JZOI2010]数字计数
[题解][P2602ZJOI2010]数字计数 乍看此题,感觉直接从数字的位上面动手,感觉应该很容易. 但是仔细看数据范围,发现如果不利用计数原理,肯定会超时,考虑数码出现的特征: \(A000\)到 ...
- 我的Java开发学习之旅------>工具类:将播放器的进度值转换成相应的时间格式
在我的博客<我的Java开发学习之旅------>Java 格式化类(java.util.Formatter)基本用法,地址:http://blog.csdn.net/ouyang_pen ...
- LeetCode:砖墙【554】
LeetCode:砖墙[554] 题目描述 你的面前有一堵方形的.由多行砖块组成的砖墙. 这些砖块高度相同但是宽度不同.你现在要画一条自顶向下的.穿过最少砖块的垂线. 砖墙由行的列表表示. 每一行都是 ...
- Java基础教程:JDBC编程
Java基础教程:JDBC编程 1.什么是JDBC JDBC 指 Java 数据库连接,是一种标准Java应用编程接口( JAVA API),用来连接 Java 编程语言和广泛的数据库. JDBC A ...
- 在win7下使用git和gitlab进行code review
1.安装 Git-2.6.3-64-bit.exe 下载地址:http://pan.baidu.com/s/1hqGvwnq 2.根据收到的邮件进入gitlab网站,并修改密码登陆 3.新建一个文件 ...
- git显示颜色配置
启用默认的颜色设置可以使用如下命令 git config --global color.ui true 如果不喜欢花花绿绿的颜色,可以将其关闭: git config --global color.u ...
- 一篇文章教你如何用R进行数据挖掘
一篇文章教你如何用R进行数据挖掘 引言 R是一种广泛用于数据分析和统计计算的强大语言,于上世纪90年代开始发展起来.得益于全世界众多 爱好者的无尽努力,大家继而开发出了一种基于R但优于R基本文本编辑器 ...
- IntelliJ IDEA 中详细图解记录如何连接MySQL数据库
- wordpress汇总(持续更新)
在wordpress上新建编辑了几个页面,总是不能正常发布预览.经调查是由于固定链接的设置有问题导致的.打开左侧栏目“设置”中的固定链接项,可以看到目前所选的是“自定义结构”型.将其更改为“朴素”型后 ...