.net 多线程 Thread ThreadPool Task

先准备一个耗时方法

/// <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("第二个"))

原文地址:https://www.cnblogs.com/Rookieflying/p/10428673.html

时间: 2024-07-29 00:15:38

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

[多线程]thread,threadpool,task及TPL知识点整理

简单理解 Thread:是一个指令序列,个体对象. Threadpool:在使用Thread的过程中,程序员要为每个希望并发的序列new一个线程,很麻烦,因此希望有一个统一管理线程的方法,程序员就不需要关注线程的申请管理问题,所以就对Thread进行一系列封装,有了ThreadPool.使用Threadpool,把需要并发的序列添加进线程池,线程池根据其线程列表中的线程的空闲情况,动态为并发序列申请线程. Task:再后来,程序员发现在使用Threadpool的过程当中还是存在很多不便,比如:(

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

1 进程-线程-多线程,同步和异步2 异步使用和回调3 异步参数4 异步等待5 异步返回值 5 多线程的特点:不卡主线程.速度快.无序性7 thread:线程等待,回调,前台线程/后台线程, 8 threadpool:线程池使用,设置线程池,ManualResetEvent9 Task初步接触 10 task:waitall waitany continueWhenAny continueWhenAll  11并行运算Parallel 12 异常处理.线程取消.多线程的临时变量和lock13 A

C#中 Thread,Task,Async/Await,IAsyncResult 的那些事儿!

说起异步,Thread,Task,async/await,IAsyncResult 这些东西肯定是绕不开的,今天就来依次聊聊他们 1.线程(Thread) 多线程的意义在于一个应用程序中,有多个执行部分可以同时执行:对于比较耗时的操作(例如io,数据库操作),或者等待响应(如WCF通信)的操作,可以单独开启后台线程来执行,这样主线程就不会阻塞,可以继续往下执行:等到后台线程执行完毕,再通知主线程,然后做出对应操作! 在C#中开启新线程比较简单 static void Main(string[]

C#多线程和异步——Task和async/await详解

阅读目录 一.什么是异步 二.Task介绍 1 Task创建和运行 2 Task的阻塞方法(Wait/WaitAll/WaitAny) 3 Task的延续操作(WhenAny/WhenAll/ContinueWith) 4 Task的任务取消(CancellationTokenSource) 三.异步方法(async/await) 回到顶部 一.什么是异步 同步和异步主要用于修饰方法.当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法:当一个方法被调用时

Java基础第八天听课总结(2)--多线程&Thread

进程 在任务管理器中查看进程,应用程序对应一个进程 进程之间的内存是隔离的,进程间是通过套接字通信Socket通信 什么是线程? ------------------------------ 线程是程序执行过程中,并发执行的代码段 线程之是可以共享内存. 线程的执行是从上往下按序执行的. 创建线程方式一 继承Thread 子类覆盖中的run方法,将线程执行的代码存放在run中 建立子类对象的同时线程也被创建. 通过调用start方法开启线程 Thread是线程类 start() //通知CPU可

2.匿名类,匿名类对象,private/protected/public关键字、abstract抽象类,抽象方法、final关键字的使用,多线程Thread类start方法原理

package com.bawei.multithread; //注意:模板方法我们通常使用抽象类或者抽象方法!这里我们为了方便在本类中使用就没有使用抽象类/抽象方法 public class TemplateThread { //如果这个方法不想被子类或者别人随意改动[这样子类就不能覆写该方法了],这里方法就要设置为final方法 public final void println(String message){ System.out.println("###################

关于多线程Thread.Stop()破坏原子性

  public class Main { public static void main(String[] args) { // TODO Auto-generated method stub MutiThread t=new MutiThread(); Thread t1=new Thread(t); /*多线程断点调试,错误结果,如果在此处执行断点,t1执行完毕,numa回复正确状态-------此处注意*/ t1.start(); for(int i=0;i<5;i++){ new Th

多线程Thread,线程池ThreadPool

首先我们先增加一个公用方法DoSomethingLong(string name),这个方法下面的举例中都有可能用到 1 #region Private Method 2 /// <summary> 3 /// 一个比较耗时耗资源的私有方法 4 /// </summary> 5 /// <param name="name"></param> 6 private void DoSomethingLong(string name) 7 { 8

java 多线程--- Thread Runnable Executors

java 实现多线程的整理: Thread实现多线程的两种方式: (1)继承 Thread类,同时重载 run 方法: class PrimeThread extends Thread { long minPrime; primeThread(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger than minPrime } } PrimeThread p = new