职务并行库,的这些事情

1.异步和三十二线程的差距?
举重若轻太大分别。异步是目标,使用八线程完毕。想想AJAX异步加载,不正是不想让浏览器分界面卡住嘛,所以在先后中对于一些单独的操作,比方写日记,我们不想等它变成后再施行别的操作(因为写日记只是记录和使用提供的坚守非亲非故),可以独自开八个线程来实践施行写日记的操作。

接上文 10二线程编制程序学习笔记——基础

谈到异步,Thread,Task,async/await,IAsyncResult
这一个东西必定是绕不开的,前几日就来所有人家聊聊他们

说到异步,Thread,Task,async/await,IAsyncResult
这几个事物必定是绕不开的,明日就来家家户户聊聊他们

二.哪些是拾2线程?
并且进行多少个职务。为何您的次第不能够而且试行多少个职务?因为全部程序正是1个主线程,而二个线程同时只好从上至下依次完结职责。比方调控台应用,你在2个while(true)的代码里Console.WriteLine(壹)。拿这么些顺序就会在while(true)的代码里走不出来,可是1旦你展开三个其余线程,在另3个线程里while(true)并且
Console.WriteLine(贰),那调节台就足以同时打字与印刷1和2

接上文 八线程编制程序学习笔记——基础

 

 

3.thead和theadpool
C#中对于线程的敞开能够行使thead这些类来展开。theadpool是一个线程池,对于须要频发开启线程的操作是三个优化。                                  

接上文 十二线程编制程序学习笔记——基础

1.线程(Thread)

1.线程(Thread)

4.thead和theadpool

接上文十二线程编制程序学习笔记——线程同步

 

 

C#中对此线程的张开能够运用thead这么些类来拉开。theadpool是1个线程池,对于急需频发开启线程的操作是二个优化。thead和theadpool并不怎么轻便调节所以不指出使用它们开启线程,task一般来讲是用来取代theadpool的,毕竟theadpool坑太多。

接上文 二十三十二线程编制程序学习笔记——线程同步

多线程的意思在于2个应用程序中,有多个施行部分能够同时推行;对于比较耗费时间的操作(举个例子io,数据库操作),只怕等待响应(如WCF通讯)的操作,能够独立开启后台线程来执行,那样主线程就不会阻塞,能够接二连三往下实行;等到后台线程施行完成,再通报主线程,然后做出相应操作!

十②线程的意思在于一个应用程序中,有四个施行部分能够同时实践;对于比较耗费时间的操作(举个例子io,数据库操作),大概等待响应(如WCF通讯)的操作,能够独自开启后台线程来举行,那样主线程就不会堵塞,能够一而再往下施行;等到后台线程实施完结,再通报主线程,然后做出相应操作!

至C#4.0起,线程建议利用task。task会依据你线程的天职,来决定个中是采纳thead还是theadpool来产生你钦命的义务。那是它壮大的地点。

接上文 十二线程编制程序学习笔记——线程同步

 

 

伍.数目安全难题
数量安全主题素材。也有人称之为重入和聚合安全难题。那是因为在十二线程编制程序下,多个线程同时操作1个数额,会形成数据变动的莫明其妙不合乎您的急需,一般有四个章程,笔者认为最简便易行的正是运用lock锁住这几个数据,不让别的线程访问只让日前线程访问。

接上文
多线程编制程序学习笔记——线程池

在C#中展开新线程相比简单

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

接上文 二10四线程编制程序学习笔记——线程池

 

 

接上文四线程编程学习笔记——线程池

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(“这是后台线程调用”);

}

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(“那是后台线程调用”);

}

前方我们上学了什么是线程,线程之间的共同,使用线程池。使用线程池能够削减大家大批量长时间操作的并行线程所用的操作系统能源。

 

 

在net framework
四.0中微软又提供了二个新的异步操作的成效,叫做任务并行库。义务并行库的为主是职务。二个职分代表了二个异步操作,譔操作能够经过四种办法运转,能够利用或不利用独立的线程。

施行结果如下图

实行结果如下图

两个任务能够透过种种主意和别的任务组合起来使用。举例,能够而且开启四个职分,等待全体职务达成,再起三个职务拓展操作。一个职责能够有多少个别的职务组成,这个义务也得以依次具有和煦的子任务。

 

 

C#5.0及随后的版本都曾经嵌入了对TPL的支撑,允许大家使用await与async关键字张开职责推行。

澳门葡京备用网址 1

澳门葡京备用网址 2

以下示例,大家使用.Net Framework
4.五之后版本。

 

 

壹、 成立职务

能够看看在运营后台线程之后,主线程继续往下实行了,并不曾等到后台线程实行完事后。

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

上边包车型客车言传身教,大家运用task构造函数创建了多个任务。大家传入了2个lambda表达式做为操作职分。然后利用start运转义务。

 

 

跟着,大家利用task.Run和task.startNew方法来运行七个职务。与使用task构造函数差别之处,在于那七个被创建的职分会登时实施。所以不必显式地调用
那么些职责的Start方法。从task一到task4全部义务都是放在线程池中实行的,数次实践,可以开采施行顺序是不雷同的。

1.1 线程池

 

试想一下,若是有大气的天职急需管理,举个例子网址后台对于HTTP请求的管理,那是还是不是要对每三个呼吁创制1个后台线程呢?显明不合适,那会占领大批量内部存款和储蓄器,而且壹再地创建的经过也会严重影响速度,那如何是好吧?

 

线程池就是为着化解这一难题,把创制的线程存起来,酿成三个线程池(里面有七个线程),当要拍卖职务时,若线程池中有空闲线程(前多少个义务试行到位后,线程不会被回收,会被设置为空闲状态),则直接调用线程池中的线程实施(例asp.net管理机制中的Application对象),使用事例:

 

for (int i = 0; i < 10; i++)

{

    ThreadPool.QueueUserWorkItem(m =>

    {

       
Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString());

    });

}

Console.Read();

 

运作结果:

 

澳门葡京备用网址 3

 

能够观察,即便举行了十四次,但并未创立十个线程。

 

1.2 信号量(Semaphore)

 

Semaphore担任协和线程,能够限制对某1财富访问的线程数量,那里对SemaphoreSlim类的用法做叁个轻巧的例子:

 

static SemaphoreSlim semLim = new 塞马phoreSlim(三);
//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();

}

 

执行结果如下:

 

澳门葡京备用网址 4

 

澳门葡京备用网址 5

 

能够见到,刚开端唯有两个线程在施行,当二个线程实施落成并释放之后,才会有新的线程来实行方式!

 

除此而外SemaphoreSlim类,还足以选拔塞马phore类,以为越是灵活,感兴趣的话可以搜一下,那里就不做示范了!

 

1.1 线程池

 

试想一下,假若有大气的任务急需管理,举个例子网址后台对于HTTP请求的处理,那是不是要对每三个请求创立三个后台线程呢?显明不合适,那会攻克多量内部存款和储蓄器,而且往往地创设的经过也会严重影响进程,这怎么做呢?

 

线程池正是为着化解那一标题,把创设的线程存起来,产生1个线程池(里面有五个线程),当要拍卖职责时,若线程池中有闲暇线程(前二个任务施行到位后,线程不会被回收,会被设置为空闲状态),则向来调用线程池中的线程实行(例asp.net管理体制中的Application对象),使用事例:

 

for (int i = 0; i < 10; i++)

{

    ThreadPool.QueueUserWorkItem(m =>

    {

       
Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString());

    });

}

Console.Read();

 

运行结果:

 

澳门葡京备用网址 6

 

能够看看,尽管举行了11次,但并不曾创建1三个线程。

 

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();

}

 

实行结果如下:

 

澳门葡京备用网址 7

 

澳门葡京备用网址 8

 

能够见见,刚初始唯有多个线程在实行,当贰个线程施行达成并释放之后,才会有新的线程来试行措施!

 

除了SemaphoreSlim类,还是能使用Semaphore类,感到越来越灵敏,感兴趣的话可以搜一下,那里就不做示范了!

 

Task5,由于大家标识为了长日子运作,所以是三个单独的线程,不是线程池中的线程来运作的。

2.Task

 

Task是.NET四.0进入的,跟线程池ThreadPool的功效类似,用Task开启新职务时,会从线程池中调用线程,而Thread每回实例化都会创立两个新的线程。

 

Console.WriteLine(“主线程运营”);

//Task.Run运营3个线程

//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(“主线程截止”);

 

施行结果如下:

 

澳门葡京备用网址 9

 

翻开新职务的章程: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);

}

 

施行结果:

 

澳门葡京备用网址 10

 

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

 

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(“主线程甘休”);

 

实行结果如下:

 

澳门葡京备用网址 11

 

展开新职分的艺术: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);

}

 

执行结果:

 

澳门葡京备用网址 12

 

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

 

  1. 代码如下:

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(“主线程甘休”);

 

运作结果:

 

澳门葡京备用网址 13

 

经过task.Result能够取到重返值,若取值的时候,后台线程还没执行完,则会等待其实行达成!

 

差不多提一下:

 

Task任务能够经过CancellationTokenSource类来打消,感到用得不多,用法相比较轻便,感兴趣的话能够搜一下!

 

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(“主线程结束”);

 

运作结果:

 

澳门葡京备用网址 14

 

透过task.Result能够取到再次回到值,若取值的时候,后台线程还没实践完,则会等待其举办完成!

 

大约提一下:

 

Task义务能够透过CancellationTokenSource类来打消,认为用得不多,用法相比简单,感兴趣的话能够搜一下!

 

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成对出现才有意义,看看运维结果:

 

澳门葡京备用网址 15

 

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

 

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

 

现在把GetString方法中的那行注释加上,运行的结果是:

 

澳门葡京备用网址 16

 

世家能够看到,在碰到await关键字后,未有继续推行GetStrLengthAsync方法后边的操作,也尚无及时反回到main函数中,而是举办了GetString的率先行,以此能够推断await那里并从未开启新的线程去推行GetString方法,而是以联合的艺术让GetString方法试行,等到实践到GetString方法中的Task<string>.Run()的时候才由Task开启了后台线程!

 

那正是说await的功力是如何吗?

 

能够从字面上通晓,上面提到task.wait能够让主线程等待后台线程试行完结,await和wait类似,一样是等待,等待Task<string>.Run()开端的后台线程推行落成,差异的是await不会堵塞主线程,只会让GetStrLengthAsync方法暂停执行。

 

那正是说await是怎么变成的吗?有未有展开新线程去等待?

 

澳门葡京备用网址 17

 

唯有多少个线程(主线程和Task开启的线程)!至于怎么产生的(笔者也不知道……>_<),我们风趣味的话钻探下呢!

 

3. async/await

 

async/await是C#伍.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成对出现才有意义,看看运维结果:

 

澳门葡京备用网址 18

 

能够看出来,main函数调用GetStrLengthAsync方法后,在await从前,皆以手拉手实行的,直到境遇await关键字,main函数才回去继续实践。

 

那么是或不是是在遭受await关键字的时候程序自动开启了3个后台线程去施行GetString方法吧?

 

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

 

澳门葡京备用网址 19

 

世家能够见见,在蒙受await关键字后,未有继续实行GetStrLengthAsync方法前边的操作,也尚未即时反回到main函数中,而是举行了GetString的率先行,以此能够判别await那里并未打开新的线程去推行GetString方法,而是以1头的法子让GetString方法推行,等到实施到GetString方法中的Task<string>.Run()的时候才由Task开启了后台线程!

 

那么await的功能是何许啊?

 

能够从字面上精晓,上边提到task.wait能够让主线程等待后台线程施行完结,await和wait类似,同样是伺机,等待Task<string>.Run()初始的后台线程施行落成,不一样的是await不会卡住主线程,只会让GetStrLengthAsync方法暂停实施。

 

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

 

澳门葡京备用网址 20

 

唯有七个线程(主线程和Task开启的线程)!至于怎么办到的(笔者也不知道……>_<),大家风乐趣的话研讨下啊!

 

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks; namespace ThreadTPLDemo{    class Program    {        static void Main(string[] args)        {            Console.WriteLine("Task 运行示例 ————{0}",DateTime.Now);           var task1 = new Task => TaskOper("Task1"));            var task2 = new Task => TaskOper("Task2"));            task1.Start();            task2.Start();                       Task.Factory.StartNew => TaskOper("Task 3"));Task.Run => TaskOper("Task 4"));             //长时间运行            Task.Factory.StartNew => TaskOper("Task 5"),TaskCreationOptions.LongRunning);                      Thread.Sleep(1000);            Console.ReadKey();        }        private static void TaskOper(string  name)        {                       Console.WriteLine("Task 运行在 线程 ID:{0} 上,这个线程是不是线程池中的线程:{1},名称: {2}",            Thread.CurrentThread.ManagedThreadId,Thread.CurrentThread.IsThreadPoolThread, name);         }    }} 

4.IAsyncResult

 

IAsyncResult自.NET1.一起就有了,包涵可异步操作的措施的类必要贯彻它,Task类就贯彻了该接口

 

 

澳门葡京备用网址 21

 

在不依附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);

 

关键步骤就是革命字体的有个别,运维结果:

 

澳门葡京备用网址 22

 

和Task的用法差距不是十分大!result.AsyncWaitHandle.WaitOne()就恍如Task的Wait。

 

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);

 

运转结果:

 

澳门葡京备用网址 23

 

循环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);

4.IAsyncResult

 

IAsyncResult自.NET一.一起就有了,包蕴可异步操作的主意的类必要完毕它,Task类就兑现了该接口

 

 

澳门葡京备用网址 24

 

在不借助于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);

 

关键步骤正是革命字体的有个别,运行结果:

 

澳门葡京备用网址 25

 

和Task的用法差距不是非常大!result.AsyncWaitHandle.WaitOne()就类似Task的Wait。

 

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);

 

运作结果:

 

澳门葡京备用网址 26

 

循环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);

贰.运营结果如下图。笔者把程序运维了三遍。请自行查看分歧之处。

 

 

澳门葡京备用网址 27

陆.异步的回调

 

为了简洁(偷懒),文中全部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();

 

实行结果:

 

澳门葡京备用网址 28

 

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();

 

举行结果:

 

澳门葡京备用网址 29

 

ContinueWith()方法能够让该后台线程继续实施新的天职。

 

Task的选取大概比较灵敏的,咱们能够琢磨下,好了,以上正是全体内容了,篇幅和才干都有限,希望对大家有用!

陆.异步的回调

 

为了简洁(偷懒),文中全数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();

 

奉行结果:

 

澳门葡京备用网址 30

 

OnCompleted中的代码会在义务实施到位之后施行!

 

别的task.ContinueWith()也是3个重要的点子:

 

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(“第1个职务落成啦!作者是第一个职责”);});

Console.WriteLine(“主线程甘休”);

Console.Read();

 

实施结果:

 

澳门葡京备用网址 31

 

ContinueWith()方法能够让该后台线程继续实施新的职分。

 

Task的应用依然相比灵活的,我们能够研商下,好了,以上正是全体内容了,篇幅和技术都有限,希望对大家有用!

2、 使用任务实行基本的操作

本示例是从职责中取得结果值。大家因此差别的实施结果来呈现在线程池中实践与在主线程中施行的分化之处。

  1. 代码如下:

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks; namespace ThreadTPLDemo{ class Program { static void Main(string[] args) { Console.WriteLine(“Task 基本操作 ————”); TaskOper(“—-主线程Task运转”); Task task1 =CreateTask(“Task一”); task壹.Start(); string result = task壹.Result; Console.WriteLine(” 运转结果——{0}”, result); Task task二 = CreateTask(“Task2″); task二.RunSynchronously(); result = task一.Result; Console.WriteLine(” 运维结果——{0}”, result); Task task3 = CreateTask(“Task3″); task3.Start(); while(!task三.IsCompleted) { Console.WriteLine(” 状态——{0}”, task叁.Status); Thread.Sleep(500); } Console.WriteLine(” ——状态—{0}”, task3.Status); result = task三.Result; Console.WriteLine(” 运转结果——{0}”, result); Console.ReadKey(); } private static string TaskOper(string name) { Console.WriteLine(“Task 线程 ID:{0} 上,是或不是线程池中的线程:{一},名称: {二}”, Thread.CurrentThread.ManagedThreadId,Thread.CurrentThread.IsThreadPoolThread, name); Thread.Sleep(两千); return string.Format(“线程ID:{0},名称:{一}”, Thread.CurrentThread.ManagedThreadId,name); } static Task CreateTask(string name) { return new Task => TaskOper; } }}

2.程序运维结果如下图。

澳门葡京备用网址 32

率先直接运维TaskOper方法,依据程序运营结果,我们得以掌握那些情势是被一同实行的。

下一场大家运转了task一,使用start方法运维任务并等候结果。那几个任务会被放在线程池中运作,而且主线程会等待,直到义务完成并回到结果。

Task2与task1相似,Task二通过RunSynchronously()方法运转的。这么些职分运营在主线程中,那个职务的出口与TaskOper方法输出结果一样。那就是task的优势,可以运用task对TaskOper方法进行优化,可避防止使用线程池来施行一些实行时间尤其短的操作。

Task三运作task一的法子,可是这一次未有阻塞主线程,只是在职务到位在此之前循环打字与印刷出任务情况。

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website