先准备一个耗时方法
/// <summary>
/// 耗时方法
/// </summary>
/// <param name="name"></param>
private void DoSomeThing(string name)
{
                 Console.WriteLine($"开始执行{name}, {Thread.CurrentThread.ManagedThreadId.ToString("00")} ,{DateTime.Now}");
                 int num = 1;

for (int i = 0; i < 100000000; i++)
                 {
                                 num++;
                 }
                 Thread.Sleep(1000);

Console.WriteLine($"结束执行{name}, {Thread.CurrentThread.ManagedThreadId.ToString("00")} ,{DateTime.Now},{num}");
}

 
 
.net Framework框架1.0和1.1时期,多线程,用Thread
 
ThreadStart  threadStart = new ThreadStart(()=>this.DoSomeThing("Thread"));
Thread thread = new Thread(threadStart);
thread.Start();// 开始执行多线程任务了。
 
//thread.Start();默认是前台线程,UI退出后,还是会继续执行完,如果thread.IsBackgroud=true;//就变成主线程关闭就直接关闭了
 
thread.Join();//这个方法是让主线程等着当前线程完成之后再执行
 
thread.Suspend();//暂停  过时方法不推荐
thread.Resume();//重启  过时方法不推荐
thread.Abort();//销毁  过时方法不推荐
 
基于Thread封装一个支持回调
private void ThreadWithCallback(ThreadStart threadStart  Action callback)
{
          ThreadStart  startNew = new ThreadStart(
                  ()=>
                     {
                             threadStart.Invoke();//执行传入的线程方法
                             callback.Invoke(); //执行回调函数
                     } 
             );
          Thread thread = new Thread(startNew);
           thread.Start();
}
 
调用这个方法:
ThreadStart threadStart = new ThreadStart(() => this.DoSomeThing("Thread"));
 Action callback = () => Console.WriteLine("这是回调函数");
 
this.ThreadWithCallback(threadStart , callback );
 
 
/// <summary>
/// 基于Thread封装带返回的
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="funcT"></param>
/// <returns></returns>
private Func<T> ThreadWithReturn<T>(Func<T> funcT)
{
           T t = default(T);

ThreadStart startNew = new ThreadStart(()=> {
            t = funcT.Invoke();
            });
            Thread thread = new Thread(startNew);
            thread.Start();
            return new Func<T>(()=> 
            {
                thread.Join();
                return t;
             });
}

 
调用这个方法
{
Func<int> func = this.ThreadWithReturn(() => 222);

Console.WriteLine( func.Invoke());

}

 
.net Framework框架2.0时期,多线程,用ThreadPool
 
ThreadPool.QueueUserWorkItem(o=>
{
          Thread.sleep(2000);
           this.DosomeThing("ThreadPool");
} //这个就是开启一个子线程。
 
如果要控制等待,就用
 ManualResetEvent mre = new ManualResetEvent(false);//默认填false
ThreadPool.QueueUserWorkItem(o => {
            Thread.Sleep(2000);
            this.DoSomeThing("ThreadPool");
            mre.Set();//这个设置之后
});
            mre.WaitOne();//当mre.Set之后,主线程就可以等待子线程执行完成之后再执行
             
            Console.WriteLine($"this is end ");
 
.net Framework框架3.0时期,多线程,用Task
 
Task.Run(()=>this.DoSomeThing("task")); //就开启执行子线程了
 
推荐使用Task的原因:1.使用的是线程池的线程,全部都是后台线程
                                    2、Api很强大
 
TaskFactory taskFactory = Task.Factory();
taskFactory.StartNew(()=>this.DoSomeThing("task1"));//跟Task.Run的效果一样
taskFactory.StartNew(()=>this.DoSomeThing("task2"));
taskFactory.StartNew(()=>this.DoSomeThing("task3"));
taskFactory.StartNew(()=>this.DoSomeThing("task4"));
taskFactory.StartNew(()=>this.DoSomeThing("task5"));//执行多个子线程
 
需要多线程加快速度,同时又要求全部完成后,执行新的任务
多业务操作希望并发,但是全部完成后,执行新的任务
 
List<Task> tkList = new List<Task>();
 
tkList.Add(taskFactory.StartNew(()=>this.DoSomeThing("task1")));
tkList.Add(taskFactory.StartNew(()=>this.DoSomeThing("task2")));
tkList.Add(taskFactory.StartNew(()=>this.DoSomeThing("task3")));
 
Task.WaitAll(tkList.toArray());
ConSole.WriteLine("全部完成之后,执行任务");
 
 
需要多线程加快速度,同时又要求一个任务完成后,执行新的任务
多业务操作希望并发,但是一个任务完成后,执行新的任务
Task.WaitAny(tkList.toArray());
ConSole.WriteLine("一个任务完成之后,执行任务");
 
不过两个方法同时使用的时候,WaitAny放在WaitAll前面。
 
但是上面2个方法都会卡住UI界面
 
还有2个方法也可以执行同样的任务,而且不卡界面,类似回调
 
taskFactory.ContinueWhenAll(tasks.ToArray(), tList => { Console.WriteLine("全部执行完之后执行,而且不卡界面"); });
 

taskFactory.ContinueWhenAny(tasks.ToArray(), t => { Console.WriteLine("执行一个任务后,执行,不卡界面"); });

 
4种方法可以一起使用,如果想先执行不卡界面的方法,后执行Task.WaitAll的方法,就可以先把这2个方法也添加进集合里面
tasks.Add(taskFactory.ContinueWhenAll(tasks.ToArray(), tList => { Console.WriteLine("全部执行完之后执行,而且不卡界面"); }));

tasks.Add(taskFactory.ContinueWhenAny(tasks.ToArray(), t => { Console.WriteLine("执行一个任务后,执行,不卡界面"); }));

 
Task.WaitAny(tkList.toArray());
ConSole.WriteLine("一个任务完成之后,执行任务");
Task.WaitAll(tkList.toArray());
ConSole.WriteLine("全部完成之后,执行任务");
 
 
可以给每个子线程,取一个标识
Task tack= taskFactory.StartNew(t => Console.WriteLine("新的一个任务"),"标识Token"); //设置标识
Console.WriteLine(tack.AsyncState.ToString());//获取标识并且打印 tack.AsyncState
 
获取返回值
//Task<int> task = taskFactory.StartNew(()=>123456);
//int result = task.Result;
//Console.WriteLine(result);
 
 
一个线程执行后马上执行另一个
taskFactory.StartNew(t=>this.DoSomeThing("第一个方法")).ContinuWith(t=>ConSole.WriteLine("第二个"))
 
 
 

.net 多线程 Thread ThreadPool Task的更多相关文章

  1. 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 ...

  2. 异步多线程 Thread ThreadPool Task

    一.线程 Thread ThreadPool 线程是Windows任务调度的最小单位,线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针.程序计数器等),但代码区是共享的,即不同的线程可以 ...

  3. .NET多线程(Thread,ThreadPool,Task,Async与Await)

    .NET多线程是什么? 进程与线程 进程是一种正在执行的程序. 线程是程序中的一个执行流. 多线程是指一个程序中可以同时运行多个不同的线程来执行不同的任务. .NET中的线程 Thread是创建和控制 ...

  4. 从Thread,ThreadPool,Task, 到async await 的基本使用方法解读

    记得很久以前的一个面试场景: 面试官:说说你对JavaScript闭包的理解吧? 我:嗯,平时都是前端工程师在写JS,我们一般只管写后端代码. 面试官:你是后端程序员啊,好吧,那问问你多线程编程的问题 ...

  5. Thread,ThreadPool,Task, 到async await 的基本使用方法和理解

    很久以前的一个面试场景: 面试官:说说你对JavaScript闭包的理解吧? 我:嗯,平时都是前端工程师在写JS,我们一般只管写后端代码. 面试官:你是后端程序员啊,好吧,那问问你多线程编程的问题吧. ...

  6. 异步和多线程,委托异步调用,Thread,ThreadPool,Task,Parallel,CancellationTokenSource

    1 进程-线程-多线程,同步和异步2 异步使用和回调3 异步参数4 异步等待5 异步返回值 5 多线程的特点:不卡主线程.速度快.无序性7 thread:线程等待,回调,前台线程/后台线程, 8 th ...

  7. Thread,ThreadPool,Task

    线程分为前台和后台.比如我们直接new一个Thread这就是前台线程. 前台线程一定会执行. 比如我们创建2个线程:1号,2号,同时执行,假设1号是主线程,1执行完了,依旧会等待2执行完成,整个程序才 ...

  8. 浅析C#中的Thread ThreadPool Task和async/await

    .net 项目中不可避免地要与线程打交道,目的都是实现异步.并发.从最开始的new Thread()入门,到后来的Task.Run(),如今在使用async/await的时候却有很多疑问. 先来看一段 ...

  9. 多线程 thread和Task的用法以及注意事项

    并行 多核线程:Task 首先引用System.Threading; 1:用静态方法:Task.Factory.StartNew()来创建了一个最简单的Task: Task.Factory.Start ...

随机推荐

  1. java 基础知识小结

    1. java 有三个求整的函数 math.floor ()  (floor 是地板的意思)  向下求整 math.ceil ()  (ceil 是天花板的意思 ) 向上求整 math.round() ...

  2. FreeSql.Repository 通用仓储层功能

    前言 好多年前,DAL 作为数据库访问层,其实是非常流行的命名方式. 不知道从什么时候开始,仓储层成了新的时尚名词.目前了解到,许多人只要在项目中看见 DAL 就会觉得很 low,但是比较可笑的一点是 ...

  3. 『Zap Möbius反演』

    Zap Description FGD正在破解一段密码,他需要回答很多类似的问题:对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a ,y<=b,并且gcd(x,y)=d.作为F ...

  4. Python基础面试,看这篇文章画重点吧,Python面试题No1

    为什么有这个系列的文章 一直想写一些更加基础的文章,但是总是想不到好的点子,最近到了就业季,一大堆学生面临就业了,正好,从Python的面试题出发,分析和解答一些常见的面试题,并且总结一些文字. 每一 ...

  5. PHP 技能精进之 PHP-FPM 多进程模型

    PHP-FPM 提供了更好的 PHP 进程管理方式,可以有效控制内存和进程.可以平滑重载PHP配置.那么当我们谈论 PHP-FPM 多进程模型的时候,作为 PHPer 的你了解多少呢? 首先,让我们一 ...

  6. maven下载及安装最详解

    maven的下载及安装 1.maven下载地址:https://maven.apache.org/download.cgi 2.将下载的安装包解压到自定义目录 3.配置环境变量 此电脑->右键属 ...

  7. 使用Ninject的一般步骤

    以下为DI控制反转个人理解烦请各位大牛指教~ 编写程序时我们应当遵循抵耦合高内聚的原则(各个功能模块互不依赖). 我们可以利用面向对象里面接口的特性来进行DI控制反转,让功能模块全部依赖接口,而不依赖 ...

  8. 开源ERP Odoo仓存功能模块深度应用(一)

    基本功能 库位 库位是一个逻辑存货区,可以是一个物理库区,可以是一个货架.货架上的一个货位.库位可以有子库位 库位有虚拟库位和实际库位,实际库位是实际存放货物的库位,虚拟库位是因复式库存记账而虚构的库 ...

  9. git rebase 合并多次提交.

    一.应用场景 为什么需要合并多个提交呢? 常常一个功能的开发,修修补补 commit 了 n 多次,带来的结果就是提交过多过杂,不够直观,究竟哪些提交是对应这个功能的呢?还有就是,如果我要将这个功能迁 ...

  10. SQL 游标的写法

    DECLARE @A varchar(200),@B varchar(200),@C datetime ----定义变量 DECLARE cursor CURSOR FOR --定义游标 SELECT ...