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

作者:编程技术

2.Task

Task是.NET4.0投入的,跟线程池ThreadPool的效果看似,用Task开启新任务时,会从线程池中调用线程,而Thread每一回实例化都会创制一个新的线程。

分分快三计划 1

Console.WriteLine("主线程启动");
//Task.Run启动一个线程
//Task启动的是后台线程,要在主线程中等待后台线程执行完毕,可以调用Wait方法
//Task task = Task.Factory.StartNew(() => { Thread.Sleep(1500); Console.WriteLine("task启动"); });
Task task = Task.Run(() => { 
    Thread.Sleep(1500);
    Console.WriteLine("task启动");
});
Thread.Sleep(300);
task.Wait();
Console.WriteLine("主线程结束");

分分快三计划 2

施行结果如下:

分分快三计划 3

敞开新义务的格局:Task.Run()大概Task.Factory.StartNew(),开启的是后台线程

要在主线程中等待后台线程推行达成,能够选择Wait方法(会以合作的章程来进行)。不用Wait则会以异步的措施来履行。

比较一下Task和Thread:

分分快三计划 4

static void Main(string[] args)
{
    for (int i = 0; i < 5; i  )
    {
        new Thread(Run1).Start();
    }
    for (int i = 0; i < 5; i  )
    {
        Task.Run(() => { Run2(); });
    }
}
static void Run1()
{
    Console.WriteLine("Thread Id ="   Thread.CurrentThread.ManagedThreadId);
}
static void Run2()
{
    Console.WriteLine("Task调用的Thread Id ="   Thread.CurrentThread.ManagedThreadId);
}

分分快三计划 5

实施结果:

分分快三计划 6

能够看出来,直接用Thread会开启5个线程,用Task(用了线程池)开启了3个!

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

聊起异步,Thread,Task,async/await,IAsyncResult 那一个东西必定是绕不开的,明日就来挨门逐户聊聊他们

1.线程(Thread)

八线程的含义在于二个应用程序中,有多少个实施部分能够同不常候实践;对于比较耗费时间的操作(比方io,数据库操作),可能等待响应(如WCF通讯)的操作,能够独自开启后台线程来实践,那样主线程就不会拥塞,能够一而再再而三往下实行;等到后台线程施行实现,再通报主线程,然后做出相应操作!

在C#中拉开新线程比较容易

分分快三计划 7

static void Main(string[] args)
{
    Console.WriteLine("主线程开始");
    //IsBackground=true,将其设置为后台线程
    Thread t = new Thread(Run) { IsBackground = true };
    t.Start();
   Console.WriteLine("主线程在做其他的事!");
    //主线程结束,后台线程会自动结束,不管有没有执行完成
    //Thread.Sleep(300);
    Thread.Sleep(1500);
    Console.WriteLine("主线程结束");
}
static void Run()
{
    Thread.Sleep(700);
    Console.WriteLine("这是后台线程调用");
}

分分快三计划 8

 实施结果如下图,

分分快三计划 9

可以见到在起步后台线程之后,主线程继续往下试行了,并从未等到后台线程奉行完事后。

1.1 线程池

试想一下,假诺有恢宏的任务须要管理,举例网址后台对于HTTP诉求的管理,这是否要对每三个伸手成立一个后台线程呢?明显不合适,那会占有大批量内存,而且再三地开创的长河也会严重影响速度,这怎么办吧?线程池就是为着化解这黄金年代主题素材,把创制的线程存起来,产生三个线程池(里面有五个线程),当要拍卖职务时,若线程池中有闲暇线程(前四个使命实行到位后,线程不会被回笼,会棉被服装置为空闲状态),则一直调用线程池中的线程试行(例asp.net处理体制中的Application对象),

行使事例:

for (int i = 0; i < 10; i  )
{
    ThreadPool.QueueUserWorkItem(m =>
    {
        Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString());
    });
}
Console.Read();

运转结果:

分分快三计划 10

能够见见,纵然进行了12回,但并从未创立11个线程。

 1.2 信号量(Semaphore)

 Semaphore担任和睦线程,能够限定对某一资源访问的线程数量

 这里对SemaphoreSlim类的用法做一个轻松的事例:

分分快三计划 11

static SemaphoreSlim semLim = new SemaphoreSlim(3); //3表示最多只能有三个线程同时访问
static void Main(string[] args)
{
    for (int i = 0; i < 10; i  )
    {
        new Thread(SemaphoreTest).Start();
    }
    Console.Read();
}
static void SemaphoreTest()
{
    semLim.Wait();
    Console.WriteLine("线程"   Thread.CurrentThread.ManagedThreadId.ToString()   "开始执行");
    Thread.Sleep(2000);
    Console.WriteLine("线程"   Thread.CurrentThread.ManagedThreadId.ToString()   "执行完毕");
    semLim.Release();
}

分分快三计划 12

奉行结果如下:

分分快三计划 13分分快三计划 14

能够见见,刚初始只有多个线程在履行,当一个线程推行完成并释放之后,才会有新的线程来实践办法!

而外SemaphoreSlim类,还足以采用Semaphore类,感觉越是灵敏,感兴趣的话能够搜一下,这里就不做示范了!

6.异步的回调

为了简洁(偷懒),文中全数Task<TResult>的重返值都以一直用task.result获取,这样只要后台职分未有实施达成的话,主线程会等待其举行完结。那样的话就和一同同样了,日常境况下不会如此用。轻易演示一下Task回调函数的运用:

Console.WriteLine("主线程开始");
Task<string> task = Task<string>.Run(() => {
    Thread.Sleep(2000); 
    return Thread.CurrentThread.ManagedThreadId.ToString(); 
});
//会等到任务执行完之后执行
task.GetAwaiter().OnCompleted(() =>
{
    Console.WriteLine(task.Result);
});
Console.WriteLine("主线程结束");
Console.Read();

实行结果:

分分快三计划 15

OnCompleted中的代码会在职责实施到位之后试行!

别的task.ContinueWith()也是二个关键的点子:

Console.WriteLine("主线程开始");
Task<string> task = Task<string>.Run(() => {
    Thread.Sleep(2000); 
    return Thread.CurrentThread.ManagedThreadId.ToString(); 
});

task.GetAwaiter().OnCompleted(() =>
{
    Console.WriteLine(task.Result);
});
task.ContinueWith(m=>{Console.WriteLine("第一个任务结束啦!我是第二个任务");});
Console.WriteLine("主线程结束");
Console.Read();

实施结果:

分分快三计划 16

ContinueWith()方法能够让该后台线程继续试行新的职务。

Task的接纳依然相比较灵活的,大家能够商讨下,好了,以上正是全体内容了,篇幅和力量都有数,希望对我们有用!

 

Thread,Task,Async/Await,IAsyncResult 的那多少个事儿!, 谈到异步,Thread,Task,async/await,IAsyncResult 那一个事物自然是绕不开的,几近期就来依次...

 3. async/await

async/await是C#5.0中生产的,先上用法:

分分快三计划 17

static void Main(string[] args)
{
    Console.WriteLine("-------主线程启动-------");
    Task<int> task = GetStrLengthAsync();
    Console.WriteLine("主线程继续执行");
    Console.WriteLine("Task返回的值"   task.Result);
    Console.WriteLine("-------主线程结束-------");
}

static async Task<int> GetStrLengthAsync()
{
    Console.WriteLine("GetStrLengthAsync方法开始执行");
    //此处返回的<string>中的字符串类型,而不是Task<string>
    string str = await GetString();
    Console.WriteLine("GetStrLengthAsync方法执行结束");
    return str.Length;
}

static Task<string> GetString()
{
   //Console.WriteLine("GetString方法开始执行")
    return Task<string>.Run(() =>
    {
        Thread.Sleep(2000);
        return "GetString的返回值";
    });
}

分分快三计划 18

async用来修饰方法,注脚那几个方法是异步的,证明的艺术的归来类型必需为:void,Task或Task<TResult>。

await必需用来修饰Task或Task<TResult>,况兼只好出今后已经用async关键字修饰的异步方法中。日常情形下,async/await成对现身才有含义,

看看运营结果:

分分快三计划 19

能够看出来,main函数调用GetStrLengthAsync方法后,在await在此之前,都是协同实行的,直到蒙受await关键字,main函数才回来继续实行。

那么是不是是在遇见await关键字的时候程序自动开启了四个后台线程去施行GetString方法吗?

于今把GetString方法中的那行注释加上,运维的结果是:

分分快三计划 20

世家可以见到,在遇见await关键字后,未有继续实行GetStrLengthAsync方法前面包车型大巴操作,也绝非及时反回到main函数中,而是举行了GetString的率先行,以此可以判明await这里并从未开启新的线程去实行GetString方法,而是以协同的方法让GetString方法推行,等到施行到GetString方法中的Task<string>.Run()的时候才由Task开启了后台线程!

那么await的职能是什么呢?

能够从字面上掌握,上面提到task.wait能够让主线程等待后台线程实行达成,await和wait相符,相疑似伺机,等待Task<string>.Run()开头的后台线程实践完结,分裂的是await不会梗塞主线程,只会让GetStrLengthAsync方法暂停推行。

那么await是怎么形成的啊?有未有张开新线程去等待?

分分快三计划 21

独有三个线程(主线程和Task开启的线程)!至于怎么完毕的(我也不知道......>_<),大家有意思味的话钻探下吧!

 5.Parallel

末段说一下在循环中拉开四线程的简易方法:

Stopwatch watch1 = new Stopwatch();
watch1.Start();
for (int i = 1; i <= 10; i  )
{
    Console.Write(i   ",");
    Thread.Sleep(1000);
}
watch1.Stop();
Console.WriteLine(watch1.Elapsed);

Stopwatch watch2 = new Stopwatch();
watch2.Start();

//会调用线程池中的线程
Parallel.For(1, 11, i =>
{
    Console.WriteLine(i   ",线程ID:"   Thread.CurrentThread.ManagedThreadId);
    Thread.Sleep(1000);
});
watch2.Stop();
Console.WriteLine(watch2.Elapsed);

运行结果:

分分快三计划 22

循环List<T>:

List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 6, 7, 8, 9 };
Parallel.ForEach<int>(list, n =>
{
    Console.WriteLine(n);
    Thread.Sleep(1000);
});

执行Action[]数组里面包车型地铁法门:

Action[] actions = new Action[] { 
   new Action(()=>{
       Console.WriteLine("方法1");
   }),
    new Action(()=>{
       Console.WriteLine("方法2");
   })
};
Parallel.Invoke(actions);

 5.Parallel

末段说一下在循环中开启十六线程的轻巧方法:

分分快三计划 23

Stopwatch watch1 = new Stopwatch();
watch1.Start();
for (int i = 1; i <= 10; i  )
{
    Console.Write(i   ",");
    Thread.Sleep(1000);
}
watch1.Stop();
Console.WriteLine(watch1.Elapsed);

Stopwatch watch2 = new Stopwatch();
watch2.Start();

//会调用线程池中的线程
Parallel.For(1, 11, i =>
{
    Console.WriteLine(i   ",线程ID:"   Thread.CurrentThread.ManagedThreadId);
    Thread.Sleep(1000);
});
watch2.Stop();
Console.WriteLine(watch2.Elapsed);

分分快三计划 24

运作结果:

分分快三计划 25

循环List<T>:

分分快三计划 26

List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 6, 7, 8, 9 };
Parallel.ForEach<int>(list, n =>
{
    Console.WriteLine(n);
    Thread.Sleep(1000);
});

分分快三计划 27

执行Action[]数组里面包车型大巴办法:

分分快三计划 28

Action[] actions = new Action[] { 
   new Action(()=>{
       Console.WriteLine("方法1");
   }),
    new Action(()=>{
       Console.WriteLine("方法2");
   })
};
Parallel.Invoke(actions);

分分快三计划 29

 3. async/await

async/await是C#5.0中出产的,先上用法:

static void Main(string[] args)
{
    Console.WriteLine("-------主线程启动-------");
    Task<int> task = GetStrLengthAsync();
    Console.WriteLine("主线程继续执行");
    Console.WriteLine("Task返回的值"   task.Result);
    Console.WriteLine("-------主线程结束-------");
}

static async Task<int> GetStrLengthAsync()
{
    Console.WriteLine("GetStrLengthAsync方法开始执行");
    //此处返回的<string>中的字符串类型,而不是Task<string>
    string str = await GetString();
    Console.WriteLine("GetStrLengthAsync方法执行结束");
    return str.Length;
}

static Task<string> GetString()
{
   //Console.WriteLine("GetString方法开始执行")
    return Task<string>.Run(() =>
    {
        Thread.Sleep(2000);
        return "GetString的返回值";
    });
}

async用来修饰方法,申明这几个法子是异步的,表明的艺术的回到类型必得为:void,Task或Task<TResult>。

await必需用来修饰Task或Task<TResult>,而且一定要出以往早就用async关键字修饰的异步方法中。日常状态下,async/await成对出现才有含义,

拜望运营结果:

分分快三计划 30

能够看出来,main函数调用GetStrLengthAsync方法后,在await以前,都以一路实行的,直到遇见await关键字,main函数才回来继续实践。

那正是说是还是不是是在遇到await关键字的时候程序自动开启了叁个后台线程去推行GetString方法吧?

近期把GetString方法中的那行注释加上,运转的结果是:

分分快三计划 31

世家能够见到,在遭遇await关键字后,未有继续实践GetStrLengthAsync方法前面包车型地铁操作,也尚无立刻反回到main函数中,而是进行了GetString的首先行,以此能够确定await这里并不曾拉开新的线程去实施GetString方法,而是以二头的法子让GetString方法履行,等到实践到GetString方法中的Task<string>.Run()的时候才由Task开启了后台线程!

那么await的意义是何等呢?

能够从字面上掌握,下边提到task.wait能够让主线程等待后台线程试行实现,await和wait近似,相通是等待,等待Task<string>.Run()最初的后台线程试行实现,差别的是await不会卡住主线程,只会让GetStrLengthAsync方法暂停推行。

那么await是怎么形成的吧?有未有展开新线程去等待?

分分快三计划 32

独有多少个线程(主线程和Task开启的线程)!至于怎么完毕的(小编也不知道......>_<),大家风野趣的话切磋下吧!

1.1 线程池

试想一下,假诺有恢宏的天职须求管理,比如网址后台对于HTTP须要的管理,那是或不是要对每一个诉求创立贰个后台线程呢?鲜明不合适,那会占有大量内部存款和储蓄器,况且数十次地创设的进度也会严重影响速度,那咋办吧?线程池便是为了消除这大器晚成标题,把创立的线程存起来,形成二个线程池(里面有多个线程),当要拍卖职务时,若线程池中有空闲线程(前多少个职分施行到位后,线程不会被回笼,会被设置为空闲状态),则向来调用线程池中的线程实践(例asp.net管理机制中的Application对象),

行使事例:

分分快三计划 33

for (int i = 0; i < 10; i  )
{
    ThreadPool.QueueUserWorkItem(m =>
    {
        Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString());
    });
}
Console.Read();

分分快三计划 34

运作结果:

分分快三计划 35

能够看见,即使实行了十二回,但并未有创建13个线程。

4.IAsyncResult

IAsyncResult自.NET1.1起就有了,饱含可异步操作的方法的类要求达成它,Task类就达成了该接口

分分快三计划 36

在不依附于Task的状态下怎么落实异步呢?

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("主程序开始--------------------");
        int threadId;
        AsyncDemo ad = new AsyncDemo();
        AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);

        IAsyncResult result = caller.BeginInvoke(3000,out threadId, null, null);
        Thread.Sleep(0);
        Console.WriteLine("主线程线程 {0} 正在运行.",Thread.CurrentThread.ManagedThreadId)
        //会阻塞线程,直到后台线程执行完毕之后,才会往下执行
        result.AsyncWaitHandle.WaitOne();
        Console.WriteLine("主程序在做一些事情!!!");
        //获取异步执行的结果
        string returnValue = caller.EndInvoke(out threadId, result);
        //释放资源
        result.AsyncWaitHandle.Close();
        Console.WriteLine("主程序结束--------------------");
        Console.Read();
    }
}
public class AsyncDemo
{
    //供后台线程执行的方法
    public string TestMethod(int callDuration, out int threadId)
    {
        Console.WriteLine("测试方法开始执行.");
        Thread.Sleep(callDuration);
        threadId = Thread.CurrentThread.ManagedThreadId;
        return String.Format("测试方法执行的时间 {0}.", callDuration.ToString());
    }
}
public delegate string AsyncMethodCaller(int callDuration, out int threadId);

关键步骤正是新民主主义革命字体的一些,运转结果:

分分快三计划 37

和Task的用法差距不是超级大!result.AsyncWaitHandle.WaitOne()就就像是Task的Wait。

6.异步的回调

文中所有Task<TResult>的再次来到值都以直接用task.result获取,那样只要后台职务未有试行实现的话,主线程会等待其实行达成,那样的话就和一块同样了(看上去一样,但事实上await的时候并不会以致线程的堵截,web程序以为不到,不过wpf,winform那样的桌面程序若不采纳异步,会促成UI线程的围堵卡塔 尔(英语:State of Qatar)。简单演示一下Task回调函数的选拔:

分分快三计划 38

Console.WriteLine("主线程开始");
Task<string> task = Task<string>.Run(() => {
    Thread.Sleep(2000); 
    return Thread.CurrentThread.ManagedThreadId.ToString(); 
});
//会等到任务执行完之后执行
task.GetAwaiter().OnCompleted(() =>
{
    Console.WriteLine(task.Result);
});
Console.WriteLine("主线程结束");
Console.Read();

分分快三计划 39

施行结果:

分分快三计划 40

OnCompleted中的代码会在职务实施到位未来推行!

其余task.ContinueWith()也是八个最首要的章程:

分分快三计划 41

Console.WriteLine("主线程开始");
Task<string> task = Task<string>.Run(() => {
    Thread.Sleep(2000); 
    return Thread.CurrentThread.ManagedThreadId.ToString(); 
});

task.GetAwaiter().OnCompleted(() =>
{
    Console.WriteLine(task.Result);
});
task.ContinueWith(m=>{Console.WriteLine("第一个任务结束啦!我是第二个任务");});
Console.WriteLine("主线程结束");
Console.Read();

分分快三计划 42

实行结果:

分分快三计划 43

ContinueWith()方法能够让该后台线程继续推行新的任务。

 1.2 信号量(Semaphore)

 Semaphore负担和睦线程,能够节制对某一能源访谈的线程数量

 这里对SemaphoreSlim类的用法做二个简便的例子:

static SemaphoreSlim semLim = new SemaphoreSlim(3); //3表示最多只能有三个线程同时访问
static void Main(string[] args)
{
    for (int i = 0; i < 10; i  )
    {
        new Thread(SemaphoreTest).Start();
    }
    Console.Read();
}
static void SemaphoreTest()
{
    semLim.Wait();
    Console.WriteLine("线程"   Thread.CurrentThread.ManagedThreadId.ToString()   "开始执行");
    Thread.Sleep(2000);
    Console.WriteLine("线程"   Thread.CurrentThread.ManagedThreadId.ToString()   "执行完毕");
    semLim.Release();
}

施行结果如下:

分分快三计划 44分分快三计划 45

能够看出,刚开端唯有四个线程在施行,当一个线程施行实现并释放之后,才会有新的线程来试行办法!

除去SemaphoreSlim类,还是还不错Semaphore类,认为越是灵敏,感兴趣的话能够搜一下,这里就不做示范了!

2.1 Task<TResult>

Task<TResult>就是有再次来到值的Task,TResult就是回来值类型。

分分快三计划 46

Console.WriteLine("主线程开始");
//返回值类型为string
Task<string> task = Task<string>.Run(() => {
    Thread.Sleep(2000); 
    return Thread.CurrentThread.ManagedThreadId.ToString(); 
});
//会等到task执行完毕才会输出;
Console.WriteLine(task.Result);
Console.WriteLine("主线程结束");

分分快三计划 47

运营结果:

分分快三计划 48

经过task.Result能够取到再次来到值,若取值的时候,后台线程还未实施完,则会等待其施行完结!

简短提一下:

Task职务能够经过CancellationTokenSource类来打消,认为用得非常少,用法比较容易,感兴趣的话能够搜一下!

1.线程(Thread)

三十二线程的意义在于三个应用程序中,有四个施行部分能够何况实践;对于相比耗费时间的操作(举例io,数据库操作),大概等待响应(如WCF通讯)的操作,能够单独开启后台线程来实行,那样主线程就不会卡住,能够世襲往下进行;等到后台线程执行完结,再通报主线程,然后做出相应操作!

在C#中张开新线程比较轻易

static void Main(string[] args)
{
    Console.WriteLine("主线程开始");
    //IsBackground=true,将其设置为后台线程
    Thread t = new Thread(Run) { IsBackground = true };
    t.Start();
   Console.WriteLine("主线程在做其他的事!");
    //主线程结束,后台线程会自动结束,不管有没有执行完成
    //Thread.Sleep(300);
    Thread.Sleep(1500);
    Console.WriteLine("主线程结束");
}
static void Run()
{
    Thread.Sleep(700);
    Console.WriteLine("这是后台线程调用");
}

 实施结果如下图,

分分快三计划 49

能够看出在开发银行后台线程之后,主线程继续往下进行了,并不曾等到后台线程实行完之后。

谈起异步,Thread,Task,async/await,IAsyncResult 必须了然

2.1 Task<TResult>

Task<TResult>就是有再次来到值的Task,TResult正是回去值类型。

Console.WriteLine("主线程开始");
//返回值类型为string
Task<string> task = Task<string>.Run(() => {
    Thread.Sleep(2000); 
    return Thread.CurrentThread.ManagedThreadId.ToString(); 
});
//会等到task执行完毕才会输出;
Console.WriteLine(task.Result);
Console.WriteLine("主线程结束");

运转结果:

分分快三计划 50

因此task.Result能够取到重临值,若取值的时候,后台线程还未实行完,则会等待其执行完成!

轻便易行提一下:

Task任务能够因此CancellationTokenSource类来裁撤,感到用得没有多少,用法比较轻易,感兴趣的话能够搜一下!

4.IAsyncResult

IAsyncResult自.NET1.1起就有了,包蕴可异步操作的办法的类供给完结它,Task类就贯彻了该接口

分分快三计划 51

在不注重Task的情状下怎么落到实处异步呢?

分分快三计划 52

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("主程序开始--------------------");
        int threadId;
        AsyncDemo ad = new AsyncDemo();
        AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);

        IAsyncResult result = caller.BeginInvoke(3000,out threadId, null, null);
        Thread.Sleep(0);
        Console.WriteLine("主线程线程 {0} 正在运行.",Thread.CurrentThread.ManagedThreadId)
        //会阻塞线程,直到后台线程执行完毕之后,才会往下执行
        result.AsyncWaitHandle.WaitOne();
        Console.WriteLine("主程序在做一些事情!!!");
        //获取异步执行的结果
        string returnValue = caller.EndInvoke(out threadId, result);
        //释放资源
        result.AsyncWaitHandle.Close();
        Console.WriteLine("主程序结束--------------------");
        Console.Read();
    }
}
public class AsyncDemo
{
    //供后台线程执行的方法
    public string TestMethod(int callDuration, out int threadId)
    {
        Console.WriteLine("测试方法开始执行.");
        Thread.Sleep(callDuration);
        threadId = Thread.CurrentThread.ManagedThreadId;
        return String.Format("测试方法执行的时间 {0}.", callDuration.ToString());
    }
}
public delegate string AsyncMethodCaller(int callDuration, out int threadId);

分分快三计划 53

关键步骤就是深浅橙字体的朝气蓬勃部分,运转结果:

分分快三计划 54

和Task的用法差别不是相当大!result.AsyncWaitHandle.WaitOne()就如Task的Wait。

2.Task

Task是.NET4.0加盟的,跟线程池ThreadPool的法力看似,用Task开启新职分时,会从线程池中调用线程,而Thread每趟实例化都会创建二个新的线程。

Console.WriteLine("主线程启动");
//Task.Run启动一个线程
//Task启动的是后台线程,要在主线程中等待后台线程执行完毕,可以调用Wait方法
//Task task = Task.Factory.StartNew(() => { Thread.Sleep(1500); Console.WriteLine("task启动"); });
Task task = Task.Run(() => { 
    Thread.Sleep(1500);
    Console.WriteLine("task启动");
});
Thread.Sleep(300);
task.Wait();
Console.WriteLine("主线程结束");

推行结果如下:

分分快三计划 55

拉开新职务的秘籍:Task.Run()或然Task.Factory.StartNew(),开启的是后台线程

要在主线程中等待后台线程施行达成,能够运用Wait方法(会以合营的法子来执行)。不用Wait则会以异步的办法来实行。

正如一下Task和Thread:

static void Main(string[] args)
{
    for (int i = 0; i < 5; i  )
    {
        new Thread(Run1).Start();
    }
    for (int i = 0; i < 5; i  )
    {
        Task.Run(() => { Run2(); });
    }
}
static void Run1()
{
    Console.WriteLine("Thread Id ="   Thread.CurrentThread.ManagedThreadId);
}
static void Run2()
{
    Console.WriteLine("Task调用的Thread Id ="   Thread.CurrentThread.ManagedThreadId);
}

实行结果:

分分快三计划 56

能够看出来,直接用Thread会开启5个线程,用Task(用了线程池)开启了3个!

本文由分分快三计划发布,转载请注明来源

关键词: 分分快三计划