CLHighlander线程池个中工小编线程与I/O线程的付出,其实入情入理利用I/O线程在简报项目或文件下载时威尼斯人娱乐

引言

引言

正文首要从线程的基本作用法,CLWrangler线程池其中工小编线程与I/O线程的付出,并行操作PLINQ等四个地点介绍10二线程的开荒。
里头委托的BeginInvoke方法以及回调函数最为常用。

I/O线程只怕轻巧遇到我们的忽视,其实在付出二10十2线程系统,更应当多留意I/O线程的操作。尤其是在ASP.NET开辟当中,只怕更三个人只会注意在客户端采用Ajax大概在服务器端使用UpdatePanel。其实入情入理施用I/O线程在简报项目或文件下载时,能尽量地回落IIS的下压力。
相互之间编制程序是Framework四.0中着力推广的异步操作方法,更值得越来越深远地读书。
指望本篇作品能对各位的求学切磋有着帮衬,当中有所错漏的地点敬请点评。

正文主要从线程的根基用法,CLBMWX3线程池在那之中工我线程与I/O线程的开支,并行操作PLINQ等四个方面介绍十二线程的支出。
当中委托的BeginInvoke方法以及回调函数最为常用。 而
I/O线程大概容易碰着我们的不经意,其实在付出二十四线程系统,更应有多留意I/O线程的操作。特别是在ASP.NET开发个中,也许更四个人只会小心在客户端选取Ajax大概在服务器端使用UpdatePanel。其实合情合理运用I/O线程在报导项目或文件下载时,能尽大概地减弱IIS的下压力。
并行编制程序是Framework四.0中着力推广的异步操作格局,更值得更深入地球科学习。
希望本篇文章能对各位的就学钻探具备支持,个中有所错漏的地方敬请点评。

 

 

 

 

目录

目录

壹、线程的概念

一、线程的概念

二、线程的基础知识

2、线程的基础知识

三、以ThreadStart方式贯彻十二线程

三、以ThreadStart格局达成二十多线程

四、CL猎豹CS陆线程池的劳力线程

四、CL宝马X5线程池的劳力线程

5、CLTucson线程池的I/O线程

5、CLTiguan线程池的I/O线程

六、异步
SqlCommand

六、异步
SqlCommand

7、并行编制程序与PLINQ

7、并行编程与PLINQ

8、计时器与锁

8、计时器与锁

 

 

 

 

 

 

 

 

1、线程的定义

1、线程的定义

 一. 壹 经过、应用程序域与线程的关系

 1. 一 进度、应用程序域与线程的关联

进度(Process)是Windows系统中的一个基本概念,它蕴涵着一个周转程序所要求的能源。进度之间是相对独立的,二个进度不或者访问另1个进度的数目(除非采纳分布式总计形式),七个经过运维的挫败也不会潜移默化别的进程的运行,Windows系统正是采取进度把工作划分为多个单身的区域的。进度能够驾驭为一个先后的主干边界。

进程(Process)是Windows系统中的3个基本概念,它富含着二个周转程序所急需的能源。进度之间是相对独立的,三个进度不能够访问另三个进度的数额(除非选择分布式总括方式),2个经过运行的停业也不会潜移默化其它进度的运营,Windows系统正是运用进程把职业划分为八个单身的区域的。进程能够了然为三个先后的中央边界。

利用程序域(AppDomain)是一个程序运营的逻辑区域,它能够视为3个轻量级的进程,.NET的先后集就是在运用程序域中运作的,三个进程能够涵盖有多少个使用程序域,一个选取程序域也得以分包八个程序集。在贰个运用程序域中包罗了3个或多个左右文context,使用前后文CL大切诺基就可见把有些特殊对象的情况放置在不相同容器个中。

利用程序域(AppDomain)是一个程序运维的逻辑区域,它能够说是二个轻量级的进度,.NET的程序集就是在行使程序域中运作的,一个进度能够分包有多少个应用程序域,一个应用程序域也足以涵盖多个程序集。在3个选用程序域中包涵了多个或四个左右文context,使用前后文CLSportage就可见把一些特殊对象的事态放置在分裂容器在那之中。

线程(Thread)是进度中的基本实行单元,在经过入口实行的率先个线程被视为那几个历程的主线程。在.NET应用程序中,都是以Main()方法作为入口的,当调用此方法时系统就会自行创立贰个主线程。线程主若是由CPU寄存器、调用栈和线程本地存储器(Thread
Local
Storage,TLS)组成的。CPU寄存器主要记录当前所施行线程的气象,调用栈首要用于保护线程所调用到的内部存款和储蓄器与数码,TLS首要用以存放线程的情况新闻。

线程(Thread)是进程中的基本举办单元,在经过入口实践的首先个线程被视为那几个进度的主线程。在.NET应用程序中,都以以Main()方法作为入口的,当调用此格局时系统就会自行创造一个主线程。线程主若是由CPU寄存器、调用栈和线程本地存款和储蓄器(Thread
Local
Storage,TLS)组成的。CPU寄存器首要记录当前所实行线程的气象,调用栈首要用来爱慕线程所调用到的内部存储器与数据,TLS主要用以存放线程的景况音信。

进程、应用程序域、线程的关联如下图,三个经过内足以包含多少个利用程序域,也有囊括四个线程,线程也能够持续于八个应用程序域个中。但在同三个时刻,线程只会处在二个运用程序域内。

进程、应用程序域、线程的涉嫌如下图,三个进度内可以包含四个使用程序域,也有囊括五个线程,线程也得以不停于多个利用程序域在这之中。但在同3个整日,线程只会处在二个行使程序域内。

 

 

威尼斯人娱乐 1

威尼斯人娱乐 2

 
鉴于本文是以介绍八线程技艺为主题,对进度、应用程序域的牵线就到此甘休。关于进度、线程、应用程序域的本领,在“C#汇总揭秘——细说进度、应用程序域与上下文”会有详尽介绍。

 
由于本文是以介绍八线程技能为焦点,对进程、应用程序域的牵线就到此甘休。关于进度、线程、应用程序域的才能,在“C#综述揭秘——细说进度、应用程序域与上下文”会有详实介绍。

 

 

1.2 多线程

1.2 多线程

在单CPU系统的多个单位时间(time
slice)内,CPU只好运转单个线程,运维顺序取决于线程的事先等第。如果在单位时间内线程未能产生实践,系统就会把线程的情形音信保存到线程的本地存款和储蓄器(TLS)
中,以便下次施行时上升执行。而拾贰线程只是系统带来的贰个假像,它在多少个单位时间内张开多少个线程的切换。因为切换频密而且单位时间更短暂,所以多线程可被当作同时运维。

在单CPU系统的2个单位时间(time
slice)内,CPU只好运转单个线程,运维顺序取决于线程的事先等第。假若在单位时间内线程未能造成实践,系统就会把线程的气象新闻保存到线程的地面存款和储蓄器(TLS)
中,以便下次实行时上涨实践。而10二线程只是系统带来的多少个假像,它在四个单位时间内开始展览多少个线程的切换。因为切换频密而且单位时间非常短暂,所以十二线程可被用作同时运转。

妥帖使用多线程能巩固系统的性质,比如:在系统请求大体量的数量时选取二十多线程,把数据输出工作付出异步线程,使主线程保持其牢固去处理别的标题。但需求专注一点,因为CPU需求开支不少的年月在线程的切换上,所以众多地行使10二线程反而会招致质量的暴跌。

适于选用二十多线程能增高系统的性质,比如:在系统请求大容积的数量时选用十二线程,把数据输出工作付出异步线程,使主线程保持其稳定去处理任何题目。但须求留意一点,因为CPU须求开支不少的时刻在线程的切换上,所以广大地运用八线程反而会导致质量的回落。

 

 

回来目录

回去目录

二、线程的基础知识

二、线程的基础知识

2.1 System.Threading.Thread类

2.1 System.Threading.Thread类

System.Threading.Thread是用来调整线程的基本功类,通过Thread能够垄断(monopoly)当前应用程序域中线程的成立、挂起、结束、销毁。

System.Threading.Thread是用来调控线程的功底类,通过Thread能够操纵当前应用程序域中线程的成立、挂起、截止、销毁。

它归纳以下常用公共性质:

它归纳以下常用公共性质:

属性名称 说明
CurrentContext 获取线程正在其中执行的当前上下文。
CurrentThread 获取当前正在运行的线程。
ExecutionContext 获取一个 ExecutionContext 对象,该对象包含有关当前线程的各种上下文的信息。
IsAlive 获取一个值,该值指示当前线程的执行状态。
IsBackground 获取或设置一个值,该值指示某个线程是否为后台线程。
IsThreadPoolThread 获取一个值,该值指示线程是否属于托管线程池。
ManagedThreadId 获取当前托管线程的唯一标识符。
Name 获取或设置线程的名称。
Priority 获取或设置一个值,该值指示线程的调度优先级。
ThreadState 获取一个值,该值包含当前线程的状态。
属性名称 说明
CurrentContext 获取线程正在其中执行的当前上下文。
CurrentThread 获取当前正在运行的线程。
ExecutionContext 获取一个 ExecutionContext 对象,该对象包含有关当前线程的各种上下文的信息。
IsAlive 获取一个值,该值指示当前线程的执行状态。
IsBackground 获取或设置一个值,该值指示某个线程是否为后台线程。
IsThreadPoolThread 获取一个值,该值指示线程是否属于托管线程池。
ManagedThreadId 获取当前托管线程的唯一标识符。
Name 获取或设置线程的名称。
Priority 获取或设置一个值,该值指示线程的调度优先级。
ThreadState 获取一个值,该值包含当前线程的状态。

 

 

二.壹.一 线程的标志符

2.1.1 线程的标志符

ManagedThreadId是确认线程的绝无仅有标记符,程序在大部情景下都是通过Thread.ManagedThreadId来甄别线程的。而Name是三个可变值,在私下认可时候,Name为3个空值
Null,开荒人士能够因此程序设置线程的名目,但那只是二个扶助功能。

ManagedThreadId是确认线程的绝无仅有标志符,程序在很多情形下都是通过Thread.ManagedThreadId来鉴定分别线程的。而Name是2个可变值,在暗中认可时候,Name为一个空值
Null,开辟人士能够由此程序设置线程的称号,但那只是一个相助作用。

 

 

二.1.二 线程的先期等级

贰.一.二 线程的事先等级

.NET为线程设置了Priority属性来定义线程实施的事先等第,里面包含八个选取,个中Normal是默许值。除非系统有特殊供给,不然不应有随便设置线程的预先等第。

.NET为线程设置了Priority属性来定义线程实践的先期品级,里面富含多少个挑选,当中Normal是私下认可值。除非系统有特殊须要,不然不应该随便设置线程的事先等第。

成员名称 说明
Lowest 可以将 Thread 安排在具有任何其他优先级的线程之后。
BelowNormal 可以将 Thread 安排在具有 Normal 优先级的线程之后,在具有 Lowest 优先级的线程之前。
Normal 默认选择。可以将 Thread 安排在具有 AboveNormal 优先级的线程之后,在具有 BelowNormal 优先级的线程之前。
AboveNormal 可以将 Thread 安排在具有 Highest 优先级的线程之后,在具有 Normal 优先级的线程之前。
Highest 可以将 Thread 安排在具有任何其他优先级的线程之前。
成员名称 说明
Lowest 可以将 Thread 安排在具有任何其他优先级的线程之后。      
BelowNormal 可以将 Thread 安排在具有 Normal 优先级的线程之后,在具有 Lowest 优先级的线程之前。      
Normal 默认选择。可以将 Thread 安排在具有 AboveNormal 优先级的线程之后,在具有 BelowNormal 优先级的线程之前。 
AboveNormal 可以将 Thread 安排在具有 Highest 优先级的线程之后,在具有 Normal 优先级的线程之前。      
Highest 可以将 Thread 安排在具有任何其他优先级的线程之前。      

 

 

2.1.叁 线程的情景

贰.一.3 线程的动静

经过ThreadState能够检查实验线程是居于Unstarted、Sleeping、Running
等等状态,它比 IsAlive 属品质提供越多的一定新闻。

由此ThreadState能够质量评定线程是处在Unstarted、Sleeping、Running
等等状态,它比 IsAlive 属质量提供越来越多的一定新闻。

前方说过,1个使用程序域中可能包括三个上下文,而透过CurrentContext能够拿走线程当前的上下文。

前方说过,1个使用程序域中或然包罗八个上下文,而因而CurrentContext可以获得线程当前的上下文。

CurrentThread是最常用的几本性质,它是用来获取当前运作的线程。

CurrentThread是最常用的二个天性,它是用以获取当前运维的线程。

 

 

2.1.4 System.Threading.Thread的方法

2.1.4 System.Threading.Thread的方法

Thread
中归纳了七个艺术来决定线程的始建、挂起、截至、销毁,以往来的例证中会平常选择。

Thread
中归纳了多少个点子来决定线程的创办、挂起、停止、销毁,以往来的例证中会平日应用。

方法名称 说明
Abort()     终止本线程。
GetDomain() 返回当前线程正在其中运行的当前域。
GetDomainId() 返回当前线程正在其中运行的当前域Id。
Interrupt() 中断处于 WaitSleepJoin 线程状态的线程。
Join() 已重载。 阻塞调用线程,直到某个线程终止时为止。
Resume() 继续运行已挂起的线程。
Start()   执行本线程。
Suspend() 挂起当前线程,如果当前线程已属于挂起状态则此不起作用
Sleep()   把正在运行的线程挂起一段时间。
方法名称 说明
Abort()     终止本线程。
GetDomain() 返回当前线程正在其中运行的当前域。
GetDomainId() 返回当前线程正在其中运行的当前域Id。
Interrupt() 中断处于 WaitSleepJoin 线程状态的线程。
Join() 已重载。 阻塞调用线程,直到某个线程终止时为止。
Resume() 继续运行已挂起的线程。
Start()   执行本线程。
Suspend() 挂起当前线程,如果当前线程已属于挂起状态则此不起作用
Sleep()   把正在运行的线程挂起一段时间。

 

 

2.壹.伍 开采实例

二.一.5 开垦实例

以下这些事例,便是经过Thread呈现当前线程消息

以下这几个例子,就是通过Thread展现当前线程音信

 1         static void Main(string[] args)
 2         {
 3             Thread thread = Thread.CurrentThread;
 4             thread.Name = "Main Thread";
 5             string threadMessage = string.Format("Thread ID:{0}\n    Current AppDomainId:{1}\n    "+
 6                 "Current ContextId:{2}\n    Thread Name:{3}\n    "+
 7                 "Thread State:{4}\n    Thread Priority:{5}\n",
 8                 thread.ManagedThreadId, Thread.GetDomainID(), Thread.CurrentContext.ContextID,
 9                 thread.Name, thread.ThreadState, thread.Priority);
10             Console.WriteLine(threadMessage);
11             Console.ReadKey();
12         }

威尼斯人娱乐 3😉

 

 1         static void Main(string[] args)
 2         {
 3             Thread thread = Thread.CurrentThread;
 4             thread.Name = "Main Thread";
 5             string threadMessage = string.Format("Thread ID:{0}\n    Current AppDomainId:{1}\n    "+
 6                 "Current ContextId:{2}\n    Thread Name:{3}\n    "+
 7                 "Thread State:{4}\n    Thread Priority:{5}\n",
 8                 thread.ManagedThreadId, Thread.GetDomainID(), Thread.CurrentContext.ContextID,
 9                 thread.Name, thread.ThreadState, thread.Priority);
10             Console.WriteLine(threadMessage);
11             Console.ReadKey();
12         }

运营结果

威尼斯人娱乐 4😉

威尼斯人娱乐 5

 

 

运作结果

二.二  System.Threading 命名空间

威尼斯人娱乐 6

在System.Threading命名空间内提供八个情势来营造多线程应用程序,当中ThreadPool与Thread是四线程开拓中最常用到的,在.NET中特意设定了多个CLEscort线程池专门用来管理线程的运作,那几个CLRubicon线程池正是经过ThreadPool类来管理。而Thread是管制线程的最直接形式,上边几节将详细介绍有关内容。

 

类     说明
AutoResetEvent 通知正在等待的线程已发生事件。无法继承此类。
ExecutionContext 管理当前线程的执行上下文。无法继承此类。
Interlocked 为多个线程共享的变量提供原子操作。
Monitor 提供同步对对象的访问的机制。
Mutex 一个同步基元,也可用于进程间同步。
Thread 创建并控制线程,设置其优先级并获取其状态。
ThreadAbortException 在对 Abort 方法进行调用时引发的异常。无法继承此类。
ThreadPool 提供一个线程池,该线程池可用于发送工作项、处理异步 I/O、代表其他线程等待以及处理计时器。
Timeout 包含用于指定无限长的时间的常数。无法继承此类。
Timer 提供以指定的时间间隔执行方法的机制。无法继承此类。
WaitHandle 封装等待对共享资源的独占访问的操作系统特定的对象。

二.二  System.Threading 命名空间

在System.Threading中的包罗了下表中的八个常用委托,个中ThreadStart、ParameterizedThreadStart是最常用到的信托。
由ThreadStart生成的线程是最直接的方法,但由ThreadStart所生成并不受线程池管理。
而ParameterizedThreadStart是为异步触发带参数的主意而设的,在下壹节将为我们逐1细说。

在System.Threading命名空间内提供五个章程来营造八线程应用程序,个中ThreadPool与Thread是八线程开采中最常用到的,在.NET中越发设定了二个CL凯雷德线程池专门用来管理线程的运行,那么些CL途胜线程池便是经过ThreadPool类来治本。而Thread是管理线程的最间接格局,上面几节将详细介绍有关内容。

委托 说明
ContextCallback 表示要在新上下文中调用的方法。
ParameterizedThreadStart 表示在 Thread 上执行的方法。
ThreadExceptionEventHandler 表示将要处理 Application 的 ThreadException 事件的方法。
ThreadStart 表示在 Thread 上执行的方法。
TimerCallback 表示处理来自 Timer 的调用的方法。
WaitCallback 表示线程池线程要执行的回调方法。
WaitOrTimerCallback 表示当 WaitHandle 超时或终止时要调用的方法。
类     说明
AutoResetEvent 通知正在等待的线程已发生事件。无法继承此类。
ExecutionContext 管理当前线程的执行上下文。无法继承此类。
Interlocked 为多个线程共享的变量提供原子操作。
Monitor 提供同步对对象的访问的机制。
Mutex 一个同步基元,也可用于进程间同步。
Thread 创建并控制线程,设置其优先级并获取其状态。
ThreadAbortException 在对 Abort 方法进行调用时引发的异常。无法继承此类。
ThreadPool 提供一个线程池,该线程池可用于发送工作项、处理异步 I/O、代表其他线程等待以及处理计时器。
Timeout 包含用于指定无限长的时间的常数。无法继承此类。
Timer 提供以指定的时间间隔执行方法的机制。无法继承此类。
WaitHandle 封装等待对共享资源的独占访问的操作系统特定的对象。

 

在System.Threading中的包括了下表中的八个常用委托,个中ThreadStart、ParameterizedThreadStart是最常用到的信托。
由ThreadStart生成的线程是最直白的方法,但由ThreadStart所生成并不受线程池管理。
而ParameterizedThreadStart是为异步触发带参数的点子而设的,在下1节将为大家逐1细说。

二.三 线程的治本措施

委托 说明
ContextCallback 表示要在新上下文中调用的方法。
ParameterizedThreadStart 表示在 Thread 上执行的方法。
ThreadExceptionEventHandler 表示将要处理 Application 的 ThreadException 事件的方法。
ThreadStart 表示在 Thread 上执行的方法。
TimerCallback 表示处理来自 Timer 的调用的方法。
WaitCallback 表示线程池线程要执行的回调方法。
WaitOrTimerCallback 表示当 WaitHandle 超时或终止时要调用的方法。

由此ThreadStart来成立四个新线程是最直白的艺术,但如此创制出来的线程比较难管理,假诺创设过多的线程反而会让系统的属性下载。有见及此,.NET为线程管理专门设置了2个CLHaval线程池,使用CL卡宴线程池系统能够更客观地保管线程的行使。全体请求的劳务都能运维于线程池中,当运转甘休时线程便会回归到线程池。通过安装,能调节线程池的最大线程数量,在呼吁凌驾线程最大值时,线程池能按照操作的先期等第来实行,让有些操作处于等候情形,待无线程回归时再执行操作。

 

基础知识就为大家介绍到此处,上边将详细介绍二十四线程的开采。

二.三 线程的管制章程

 

透过ThreadStart来创立贰个新线程是最直白的主意,但那样创制出来的线程相比难管理,如若创制过多的线程反而会让系统的质量下载。有见及此,.NET为线程管理专门设置了二个CLEnclave线程池,使用CL宝马X五线程池系统能够更合理地管理线程的应用。全部请求的劳务都能运维于线程池中,当运维截至时线程便会回归到线程池。通过安装,能调整线程池的最大线程数量,在伸手超越线程最大值时,线程池能遵照操作的优先品级来进行,让有个别操作处于等候情形,待有线程回归时再进行操作。

 

基础知识就为大家介绍到此处,上面将详细介绍四线程的开销。

归来目录

 

叁、以ThreadStart情势达成四线程

 

3.1 使用ThreadStart委托

再次来到目录

此处先以3个例证显示一下多线程带来的利润,首先在Message类中确立2个艺术ShowMessage(),里面展现了现阶段运作线程的Id,并行使Thread.Sleep(int
)
方法模拟部分工作。在main()中经过ThreadStart委托绑定Message对象的ShowMessage()方法,然后经过Thread.Start()实践异步方法。

叁、以ThreadStart方式落成多线程

 1       public class Message
 2       {
 3           public void ShowMessage()
 4           {
 5               string message = string.Format("Async threadId is :{0}",
 6                                               Thread.CurrentThread.ManagedThreadId);
 7               Console.WriteLine(message);
 8   
 9               for (int n = 0; n < 10; n++)
10               {
11                   Thread.Sleep(300);   
12                   Console.WriteLine("The number is:" + n.ToString()); 
13               }
14           }
15       }
16   
17       class Program
18       {
19           static void Main(string[] args)
20           {
21               Console.WriteLine("Main threadId is:"+
22                                 Thread.CurrentThread.ManagedThreadId);
23               Message message=new Message();
24               Thread thread = new Thread(new ThreadStart(message.ShowMessage));
25               thread.Start();
26               Console.WriteLine("Do something ..........!");
27               Console.WriteLine("Main thread working is complete!");
28               
29           }
30       }

3.1 使用ThreadStart委托

请留意运维结果,在调用Thread.Start()方法后,系统以异步方式运转Message.ShowMessage(),而主线程的操作是继续执行的,在Message.ShowMessage()完成前,主线程已到位具备的操作。

此处先以多个例子浮现一下102线程带来的功利,首先在Message类中创建贰个形式ShowMessage(),里面展现了方今运行线程的Id,并采纳Thread.Sleep(int
)
方法模拟部分工作。在main()中经过ThreadStart委托绑定Message对象的ShowMessage()方法,然后通过Thread.Start()试行异步方法。

威尼斯人娱乐 7

威尼斯人娱乐 8😉

 

 1       public class Message  2       {  3           public void ShowMessage()  4           {  5               string message = string.Format("Async threadId is :{0}",  6                                               Thread.CurrentThread.ManagedThreadId);  7               Console.WriteLine(message);  8     9               for (int n = 0; n < 10; n++) 10               { 11                   Thread.Sleep(300);    12                   Console.WriteLine("The number is:" + n.ToString());  13               } 14           } 15       } 16    17       class Program 18       { 19           static void Main(string[] args) 20           { 21               Console.WriteLine("Main threadId is:"+ 22                                 Thread.CurrentThread.ManagedThreadId); 23               Message message=new Message(); 24               Thread thread = new Thread(new ThreadStart(message.ShowMessage)); 25               thread.Start(); 26               Console.WriteLine("Do something ..........!"); 27               Console.WriteLine("Main thread working is complete!"); 28                29           } 30       }

3.2 使用ParameterizedThreadStart委托

威尼斯人娱乐 9😉

ParameterizedThreadStart委托与ThreadStart委托格外相像,但ParameterizedThreadStart委托是面向带参数方法的。注意ParameterizedThreadStart
对应措施的参数为object,此参数可认为3个值对象,也得以为3个自定义对象。

请小心运维结果,在调用Thread.Start()方法后,系统以异步格局运维Message.ShowMessage(),而主线程的操作是继续试行的,在Message.ShowMessage()完结前,主线程已到位有着的操作。

 1     public class Person
 2     {
 3         public string Name
 4         {
 5             get;
 6             set;
 7         }
 8         public int Age
 9         {
10             get;
11             set;
12         }
13     }
14 
15     public class Message
16     {
17         public void ShowMessage(object person)
18         {
19             if (person != null)
20             {
21                 Person _person = (Person)person;
22                 string message = string.Format("\n{0}'s age is {1}!\nAsync threadId is:{2}",
23                     _person.Name,_person.Age,Thread.CurrentThread.ManagedThreadId);
24                 Console.WriteLine(message);
25             }
26             for (int n = 0; n < 10; n++)
27             {
28                 Thread.Sleep(300);   
29                 Console.WriteLine("The number is:" + n.ToString()); 
30             }
31         }
32     }
33 
34     class Program
35     {
36         static void Main(string[] args)
37         {     
38             Console.WriteLine("Main threadId is:"+Thread.CurrentThread.ManagedThreadId);
39             
40             Message message=new Message();
41             //绑定带参数的异步方法
42             Thread thread = new Thread(new ParameterizedThreadStart(message.ShowMessage));
43             Person person = new Person();
44             person.Name = "Jack";
45             person.Age = 21;
46             thread.Start(person);  //启动异步线程 
47             
48             Console.WriteLine("Do something ..........!");
49             Console.WriteLine("Main thread working is complete!");
50              
51         }
52     }

威尼斯人娱乐 10

运营结果:

 

威尼斯人娱乐 11

3.2 使用ParameterizedThreadStart委托

 

ParameterizedThreadStart委托与ThreadStart委托分外相像,但ParameterizedThreadStart委托是面向带参数方法的。注意ParameterizedThreadStart
对应措施的参数为object,此参数可感到2个值对象,也足感觉贰个自定义对象。

3.叁 前台线程与后台线程

威尼斯人娱乐 12😉

留神上述多少个例证都尚未动用Console.ReadKey(),但系统依然会等待异步线程达成后才会终止。这是因为使用Thread.Start()运行的线程默以为前台线程,而系统必须等待全数前台线程运转甘休后,应用程序域才会自行卸载。

 1     public class Person
 2     {
 3         public string Name
 4         {
 5             get;
 6             set;
 7         }
 8         public int Age
 9         {
10             get;
11             set;
12         }
13     }
14 
15     public class Message
16     {
17         public void ShowMessage(object person)
18         {
19             if (person != null)
20             {
21                 Person _person = (Person)person;
22                 string message = string.Format("\n{0}'s age is {1}!\nAsync threadId is:{2}",
23                     _person.Name,_person.Age,Thread.CurrentThread.ManagedThreadId);
24                 Console.WriteLine(message);
25             }
26             for (int n = 0; n < 10; n++)
27             {
28                 Thread.Sleep(300);   
29                 Console.WriteLine("The number is:" + n.ToString()); 
30             }
31         }
32     }
33 
34     class Program
35     {
36         static void Main(string[] args)
37         {     
38             Console.WriteLine("Main threadId is:"+Thread.CurrentThread.ManagedThreadId);
39             
40             Message message=new Message();
41             //绑定带参数的异步方法
42             Thread thread = new Thread(new ParameterizedThreadStart(message.ShowMessage));
43             Person person = new Person();
44             person.Name = "Jack";
45             person.Age = 21;
46             thread.Start(person);  //启动异步线程 
47             
48             Console.WriteLine("Do something ..........!");
49             Console.WriteLine("Main thread working is complete!");
50              
51         }
52     }

在第一节曾经介绍过线程Thread有多少个属性IsBackground,通过把此属性设置为true,就足以把线程设置为后台线程!那时应用程序域就要主线程完结时就被卸载,而不会等待异步线程的运作。

威尼斯人娱乐 13😉

 

运营结果:

三.四 挂起线程

威尼斯人娱乐 14

为了等待其余后台线程完结后再甘休主线程,就能够动用Thread.Sleep()方法。

 

 1     public class Message
 2     {
 3         public void ShowMessage()
 4         {
 5             string message = string.Format("\nAsync threadId is:{0}",
 6                                            Thread.CurrentThread.ManagedThreadId);
 7             Console.WriteLine(message);
 8             for (int n = 0; n < 10; n++)
 9             {
10                 Thread.Sleep(300);
11                 Console.WriteLine("The number is:" + n.ToString());
12             }
13         }
14     }
15 
16     class Program
17     {
18         static void Main(string[] args)
19         {     
20             Console.WriteLine("Main threadId is:"+
21                               Thread.CurrentThread.ManagedThreadId);
22             
23             Message message=new Message();
24             Thread thread = new Thread(new ThreadStart(message.ShowMessage));
25             thread.IsBackground = true;
26             thread.Start();
27             
28             Console.WriteLine("Do something ..........!");
29             Console.WriteLine("Main thread working is complete!");
30             Console.WriteLine("Main thread sleep!");
31             Thread.Sleep(5000);
32         }
33     }

三.三 前台线程与后台线程

运作结果如下,此时使用程序域将要主线程运转5秒后自动终止

留意上述五个例证都不曾利用Console.ReadKey(),但系统还是会等待异步线程达成后才会甘休。那是因为使用Thread.Start()运行的线程默以为前台线程,而系统必须等待全体前台线程运行结束后,应用程序域才会自行卸载。

威尼斯人娱乐 15

在第3节曾经介绍过线程Thread有二天性质IsBackground,通过把此属性设置为true,就足以把线程设置为后台线程!那时应用程序域将要主线程完结时就被卸载,而不会等待异步线程的运行。

 

 

但系统不能够预见异步线程须要周转的年月,所以用经过Thread.Sleep(int)阻塞主线程并不是贰个好的消除方法。有见及此,.NET专门为等待异步线程实现支付了另三个方法thread.Join()。把地点例子中的最终一行Thread.Sleep(5000)修改为
thread.Join() 就能担保主线程在异步线程thread运营结束后才会终止。

三.四 挂起线程

 

为了等待别的后台线程完结后再截止主线程,就足以行使Thread.Sleep()方法。

3.5 Suspend 与 Resume (慎用)

威尼斯人娱乐 16😉

Thread.Suspend()与 Thread.Resume()是在Framework1.0
就已经存在的老艺术了,它们各自能够挂起、复苏线程。但在Framework2.0中就早已大名鼎鼎排斥那多少个点子。那是因为只要有些线程占用了已有个别资源,再选取Suspend()使线程短期居于挂起状态,当在别的线程调用这么些财富的时候就会唤起死锁!所以在未曾需求的景色下相应防止选用那多少个方法。

 1     public class Message  2     {  3         public void ShowMessage()  4         {  5             string message = string.Format("\nAsync threadId is:{0}",  6                                            Thread.CurrentThread.ManagedThreadId);  7             Console.WriteLine(message);  8             for (int n = 0; n < 10; n++)  9             { 10                 Thread.Sleep(300); 11                 Console.WriteLine("The number is:" + n.ToString()); 12             } 13         } 14     } 15  16     class Program 17     { 18         static void Main(string[] args) 19         {      20             Console.WriteLine("Main threadId is:"+ 21                               Thread.CurrentThread.ManagedThreadId); 22              23             Message message=new Message(); 24             Thread thread = new Thread(new ThreadStart(message.ShowMessage)); 25             thread.IsBackground = true; 26             thread.Start(); 27              28             Console.WriteLine("Do something ..........!"); 29             Console.WriteLine("Main thread working is complete!"); 30             Console.WriteLine("Main thread sleep!"); 31             Thread.Sleep(5000); 32         } 33     }

 

威尼斯人娱乐 17😉

三.6 终止线程

运行结果如下,此时使用程序域就要主线程运行伍秒后自行终止

若想终止正在运营的线程,能够应用Abort()方法。在利用Abort()的时候,将引发四个破例非凡ThreadAbortException 。
若想在线程终止前恢复生机线程的实践,能够在抓获十分后
,在catch(ThreadAbortException ex){…}
中调用Thread.ResetAbort()撤废终止。
而选取Thread.Join()能够确认保障应用程序域等待异步线程停止后才结束启动。

威尼斯人娱乐 18

 1          static void Main(string[] args)
 2          {
 3              Console.WriteLine("Main threadId is:" +
 4                                Thread.CurrentThread.ManagedThreadId);
 5  
 6              Thread thread = new Thread(new ThreadStart(AsyncThread));
 7              thread.IsBackground = true;
 8              thread.Start();
 9              thread.Join();
10  
11          }     
12          
13          //以异步方式调用
14          static void AsyncThread()
15          {
16              try
17              {
18                  string message = string.Format("\nAsync threadId is:{0}",
19                     Thread.CurrentThread.ManagedThreadId);
20                  Console.WriteLine(message);
21  
22                  for (int n = 0; n < 10; n++)
23                  {
24                      //当n等于4时,终止线程
25                      if (n >= 4)
26                      {
27                          Thread.CurrentThread.Abort(n);
28                      }
29                      Thread.Sleep(300);
30                      Console.WriteLine("The number is:" + n.ToString());
31                  }
32              }
33              catch (ThreadAbortException ex)
34              {
35                  //输出终止线程时n的值
36                  if (ex.ExceptionState != null)
37                      Console.WriteLine(string.Format("Thread abort when the number is: {0}!", 
38                                                       ex.ExceptionState.ToString()));
39                 
40                  //取消终止,继续执行线程
41                  Thread.ResetAbort();
42                  Console.WriteLine("Thread ResetAbort!");
43              }
44  
45              //线程结束
46              Console.WriteLine("Thread Close!");
47          }

 

运作结果如下

但系统不或者预言异步线程需求周转的时间,所以用经过Thread.Sleep(int)阻塞主线程并不是二个好的解决方法。有见及此,.NET专门为等候异步线程完结支付了另3个主意thread.Join()。把地方例子中的最终一行Thread.Sleep(5000)修改为
thread.Join() 就能确认保证主线程在异步线程thread运维甘休后才会停下。

威尼斯人娱乐 19

 

 

3.5 Suspend 与 Resume (慎用)

 

Thread.Suspend()与 Thread.Resume()是在Framework一.0
就曾经存在的老艺术了,它们各自能够挂起、恢复生机线程。但在Framework2.0中就曾经无人不知排斥那七个章程。那是因为假设某些线程占用了已部分能源,再使用Suspend()使线程长期处在挂起状态,当在任何线程调用这几个财富的时候就会引起死锁!所以在未曾须求的状态下应当制止选择那五个法子。

归来目录

 

四、CLLAND线程池的劳重力线程

三.陆 终止线程

4.1 关于CLR线程池

若想终止正在周转的线程,可以采取Abort()方法。在运用Abort()的时候,将抓住一个特殊极度ThreadAbortException 。 若想在线程终止前苏醒线程的实行,能够在破获卓殊后
,在catch(ThreadAbortException ex){…}
中调用Thread.ResetAbort()撤消终止。
而使用Thread.Join()能够确认保证应用程序域等待异步线程停止后才停下运转。

选用ThreadStart与ParameterizedThreadStart建立新线程十分轻易,但通过此方法创立的线程难于管理,若建立过多的线程反而会影响系统的习性。
有见及此,.NET引进CLBMWX伍线程池这几个概念。CL大切诺基线程池并不会在CL帕杰罗开头化的时候即刻制造线程,而是在应用程序要创立线程来实施职分时,线程池才开头化七个线程。线程的开始化与任何的线程一样。在做到职务之后,该线程不会自行销毁,而是以挂起的场合再次回到到线程池。直到应用程序再一次向线程池发出请求时,线程池里挂起的线程就会另行激活试行职分。那样既省去了建立线程所导致的质量损耗,也得以让几个职分反复重用同一线程,从而在应用程序生存期内节约多量开辟。

威尼斯人娱乐 20😉

注意通过CLQashqai线程池所创立的线程总是默以为后台线程,优先级数为ThreadPriority.诺玛l。

 1          static void Main(string[] args)
 2          {
 3              Console.WriteLine("Main threadId is:" +
 4                                Thread.CurrentThread.ManagedThreadId);
 5  
 6              Thread thread = new Thread(new ThreadStart(AsyncThread));
 7              thread.IsBackground = true;
 8              thread.Start();
 9              thread.Join();
10  
11          }     
12          
13          //以异步方式调用
14          static void AsyncThread()
15          {
16              try
17              {
18                  string message = string.Format("\nAsync threadId is:{0}",
19                     Thread.CurrentThread.ManagedThreadId);
20                  Console.WriteLine(message);
21  
22                  for (int n = 0; n < 10; n++)
23                  {
24                      //当n等于4时,终止线程
25                      if (n >= 4)
26                      {
27                          Thread.CurrentThread.Abort(n);
28                      }
29                      Thread.Sleep(300);
30                      Console.WriteLine("The number is:" + n.ToString());
31                  }
32              }
33              catch (ThreadAbortException ex)
34              {
35                  //输出终止线程时n的值
36                  if (ex.ExceptionState != null)
37                      Console.WriteLine(string.Format("Thread abort when the number is: {0}!", 
38                                                       ex.ExceptionState.ToString()));
39                 
40                  //取消终止,继续执行线程
41                  Thread.ResetAbort();
42                  Console.WriteLine("Thread ResetAbort!");
43              }
44  
45              //线程结束
46              Console.WriteLine("Thread Close!");
47          }

 

威尼斯人娱乐 21😉

肆.二 工小编线程与I/O线程

运营结果如下

CL奇骏线程池分为工我线程(workerThreads)与I/O线程 (completionPortThreads)
二种,工小编线程是重要用作管理CL福特Explorer内部对象的运作,I/O(Input/Output)
线程顾名思义是用以与外部系统交换音信,IO线程的细节将要下一节详细表达。

威尼斯人娱乐 22

透过ThreadPool.Get马克斯(out int workerThreads,out int
completionPortThreads )和 ThreadPool.Set马克斯( int workerThreads, int
completionPortThreads)七个艺术能够分级读取和设置CLHighlander线程池山东中华工程公司我线程与I/O线程的最大线程数。在Framework二.0中最大线程默感到贰伍*CPU数,在Framewok3.0、4.0中最大线程数默感觉250*CPU数,在前不久
I三,I伍,I柒 CPU出现后,线程池的最大值一般默以为1000、三千。
若想测试线程池中有稍许的线程正在投入使用,能够经过ThreadPool.GetAvailableThreads(
out int workerThreads,out int
completionPortThreads ) 方法。

 

应用CLGL450线程池的劳力线程1般有三种格局,一是直接通过
ThreadPool.QueueUserWorkItem() 方法,二是透过委托,下边将次第细说。

 

 

归来目录

肆.3 通过QueueUserWorkItem运营工小编线程

四、CL卡宴线程池的劳引力线程

ThreadPool线程池中带有有七个静态方法能够直接开发银行工小编线程:
一为 ThreadPool.QueueUserWorkItem(WaitCallback)
二为 ThreadPool.QueueUserWorkItem(WaitCallback,Object) 

4.1 关于CLR线程池

先把WaitCallback委托指向多个分包Object参数的无重返值方法,再使用
ThreadPool.QueueUserWorkItem(WaitCallback)
就可以异步运维此方法,此时异步方法的参数被视为null 。

利用ThreadStart与ParameterizedThreadStart建立新线程万分简单,但由此此格局创立的线程难于管理,若建立过多的线程反而会潜移默化系统的属性。
有见及此,.NET引入CL奇骏线程池这一个定义。CLCRUISER线程池并不会在CL奥德赛发轫化的时候即刻创立线程,而是在应用程序要创建线程来实施职责时,线程池才初叶化三个线程。线程的初叶化与别的的线程同样。在产生任务之后,该线程不会自行销毁,而是以挂起的场所再次来到到线程池。直到应用程序再一次向线程池发出请求时,线程池里挂起的线程就会再一次激活实施职务。那样既省去了树立线程所形成的属性损耗,也能够让七个职分反复重用同壹线程,从而在应用程序生存期内节约大批量成本。

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             //把CLR线程池的最大值设置为1000
 6             ThreadPool.SetMaxThreads(1000, 1000);
 7             //显示主线程启动时线程池信息
 8             ThreadMessage("Start");
 9             //启动工作者线程
10             ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncCallback));
11             Console.ReadKey();
12         }
13         
14         static void AsyncCallback(object state)
15         {
16             Thread.Sleep(200);
17             ThreadMessage("AsyncCallback");
18             Console.WriteLine("Async thread do work!");
19         }
20 
21         //显示线程现状
22         static void ThreadMessage(string data)
23         {
24             string message = string.Format("{0}\n  CurrentThreadId is {1}",
25                  data, Thread.CurrentThread.ManagedThreadId);
26             Console.WriteLine(message);
27         }
28     }

注意因此CL揽胜极光线程池所建立的线程总是默以为后台线程,优先级数为ThreadPriority.Normal。

运行结果

 

威尼斯人娱乐 23

四.2 工笔者线程与I/O线程

 

CLPAJERO线程池分为工作者线程(workerThreads)与I/O线程 (completionPortThreads)
三种,工作者线程是主要用作管理CLENCORE内部对象的运作,I/O(Input/Output)
线程顾名思义是用以与外部系统沟通音讯,IO线程的细节就要下壹节详细表明。

采纳 ThreadPool.QueueUserWorkItem(WaitCallback,Object)
方法能够把object对象作为参数字传送送到回调函数中。
下边例子中正是把二个string对象作为参数发送到回调函数当中。

经过ThreadPool.Get马克斯(out int workerThreads,out int
completionPortThreads )和 ThreadPool.Set马克斯( int workerThreads, int
completionPortThreads)多少个格局能够分别读取和安装CL兰德Odyssey线程池湖南中华南理教院程公司作者线程与I/O线程的最大线程数。在Framework二.0中最大线程私下认可为25*CPU数,在Framewok3.0、四.0中最大线程数默感觉250*CPU数,在近年来I叁,I伍,I七 CPU出现后,线程池的最大值一般默感觉一千、3000。
若想测试线程池中有稍许的线程正在投入使用,能够通过ThreadPool.GetAvailableThreads(
out int workerThreads,out int
completionPortThreads ) 方法。

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             //把线程池的最大值设置为1000
 6             ThreadPool.SetMaxThreads(1000, 1000);
 7           
 8             ThreadMessage("Start");
 9             ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncCallback),"Hello Elva");
10             Console.ReadKey();
11         }
12 
13         static void AsyncCallback(object state)
14         {
15             Thread.Sleep(200);
16             ThreadMessage("AsyncCallback");
17 
18             string data = (string)state;
19             Console.WriteLine("Async thread do work!\n"+data);
20         }
21 
22         //显示线程现状
23         static void ThreadMessage(string data)
24         {
25             string message = string.Format("{0}\n  CurrentThreadId is {1}",
26                  data, Thread.CurrentThread.ManagedThreadId);
27             Console.WriteLine(message);
28         }
29     }

动用CL福睿斯线程池的劳力线程壹般有两种情势,1是平素通过
ThreadPool.QueueUserWorkItem() 方法,二是通过信托,上面将逐一细说。

运行结果

 

威尼斯人娱乐 24

四.3 通过QueueUserWorkItem运行工笔者线程

 

ThreadPool线程池中蕴藏有七个静态方法能够平素开发银行工我线程: 一为
ThreadPool.QueueUserWorkItem(WaitCallback) 贰为
ThreadPool.QueueUserWorkItem(WaitCallback,Object) 

通过ThreadPool.QueueUserWorkItem运转工作者线程即便是利于,但WaitCallback委托指向的总得是二个含有Object参数的无再次来到值方法,那毋庸置疑是一种范围。若方法必要有再次回到值,也许隐含七个参数,那将多费周折。有见及此,.NET提供了另1种艺术去建立工小编线程,那便是信托。

先把WaitCallback委托指向贰个饱含Object参数的无重回值方法,再选取ThreadPool.QueueUserWorkItem(WaitCallback)
就足以异步运维此格局,此时异步方法的参数被视为null 。

 

威尼斯人娱乐 25😉

4.4  委托类       

 1     class Program  2     {  3         static void Main(string[] args)  4         {  5             //把CLR线程池的最大值设置为1000  6             ThreadPool.SetMaxThreads(1000, 1000);  7             //显示主线程启动时线程池信息  8             ThreadMessage("Start");  9             //启动工作者线程 10             ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncCallback)); 11             Console.ReadKey(); 12         } 13          14         static void AsyncCallback(object state) 15         { 16             Thread.Sleep(200); 17             ThreadMessage("AsyncCallback"); 18             Console.WriteLine("Async thread do work!"); 19         } 20  21         //显示线程现状 22         static void ThreadMessage(string data) 23         { 24             string message = string.Format("{0}\n  CurrentThreadId is {1}", 25                  data, Thread.CurrentThread.ManagedThreadId); 26             Console.WriteLine(message); 27         } 28     }

应用CLGL450线程池中的工笔者线程,最灵敏最常用的不二等秘书诀正是运用委托的异步方法,在此先简介一下委托类。

威尼斯人娱乐 26😉

当定义委托后,.NET就会自动创制贰个表示该信托的类,下边能够用反射形式突显委托类的艺术成员(对反射风乐趣的对象能够先参考一下“.NET基础篇——反射的微妙”)

运营结果

 1     class Program
 2     {
 3         delegate void MyDelegate();
 4 
 5         static void Main(string[] args)
 6         {
 7             MyDelegate delegate1 = new MyDelegate(AsyncThread);
 8             //显示委托类的几个方法成员     
 9             var methods=delegate1.GetType().GetMethods();
10             if (methods != null)
11                 foreach (MethodInfo info in methods)
12                     Console.WriteLine(info.Name);
13             Console.ReadKey();
14          }
15      }

威尼斯人娱乐 27

委托类包蕴以下多少个首要措施

 

威尼斯人娱乐 28

使用 ThreadPool.QueueUserWorkItem(WaitCallback,Object)
方法能够把object对象作为参数字传送送到回调函数中。
上边例子中正是把一个string对象作为参数发送到回调函数在那之中。

1     public class MyDelegate:MulticastDelegate
2     {
3         public MyDelegate(object target, int methodPtr);
4         //调用委托方法
5         public virtual void Invoke();
6         //异步委托
7         public virtual IAsyncResult BeginInvoke(AsyncCallback callback,object state);
8         public virtual void EndInvoke(IAsyncResult result);
9     }

威尼斯人娱乐 29😉

当调用Invoke()方法时,对应此委托的富有办法都会被试行。而BeginInvoke与EndInvoke则帮衬委托方法的异步调用,由BeginInvoke运行的线程都属于CLCR-V线程池中的工笔者线程,在上边将详细表明。

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             //把线程池的最大值设置为1000
 6             ThreadPool.SetMaxThreads(1000, 1000);
 7           
 8             ThreadMessage("Start");
 9             ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncCallback),"Hello Elva");
10             Console.ReadKey();
11         }
12 
13         static void AsyncCallback(object state)
14         {
15             Thread.Sleep(200);
16             ThreadMessage("AsyncCallback");
17 
18             string data = (string)state;
19             Console.WriteLine("Async thread do work!\n"+data);
20         }
21 
22         //显示线程现状
23         static void ThreadMessage(string data)
24         {
25             string message = string.Format("{0}\n  CurrentThreadId is {1}",
26                  data, Thread.CurrentThread.ManagedThreadId);
27             Console.WriteLine(message);
28         }
29     }

 

威尼斯人娱乐 30😉

四.5  利用BeginInvoke与EndInvoke完结异步委托方法

运行结果

先是创制一个寄托对象,通过IAsyncResult BeginInvoke(string
name,AsyncCallback callback,object state) 异步调用委托方法,BeginInvoke
方法除最终的多个参数外,其余参数都以与办法参数相对应的。通过 BeginInvoke
方法将回到贰个完成了 System.IAsyncResult
接口的对象,之后就足以行使EndInvoke(IAsyncResult )
方法就足以终结异步操作,获取委托的运作结果。

威尼斯人娱乐 31

 1     class Program
 2     {
 3         delegate string MyDelegate(string name);
 4 
 5         static void Main(string[] args)
 6         {
 7             ThreadMessage("Main Thread");
 8             
 9             //建立委托
10             MyDelegate myDelegate = new MyDelegate(Hello);
11             //异步调用委托,获取计算结果
12             IAsyncResult result=myDelegate.BeginInvoke("Leslie", null, null);
13             //完成主线程其他工作
14             ............. 
15             //等待异步方法完成,调用EndInvoke(IAsyncResult)获取运行结果
16             string data=myDelegate.EndInvoke(result);
17             Console.WriteLine(data);
18             
19             Console.ReadKey();
20         }
21 
22         static string Hello(string name)
23         {
24             ThreadMessage("Async Thread");
25             Thread.Sleep(2000);            //虚拟异步工作
26             return "Hello " + name;
27         }
28 
29         //显示当前线程
30         static void ThreadMessage(string data)
31         {
32             string message = string.Format("{0}\n  ThreadId is:{1}",
33                    data,Thread.CurrentThread.ManagedThreadId);
34             Console.WriteLine(message);
35         }
36     }

 

运营结果

因此ThreadPool.QueueUserWorkItem运行工小编线程尽管是有利,但WaitCallback委托指向的总得是贰个饱含Object参数的无重回值方法,那的确是壹种范围。若方法必要有重临值,或许隐含七个参数,那将多费周折。有见及此,.NET提供了另1种办法去建立工我线程,这正是委托。

威尼斯人娱乐 32

 

 

4.4  委托类       

4.6  善用IAsyncResult

选拔CLWrangler线程池中的工笔者线程,最灵敏最常用的章程正是使用委托的异步方法,在此先简要介绍一下委托类。

在上述例子中得以望见,借使在运用myDelegate.BeginInvoke后登时调用myDelegate.EndInvoke,这在异步线程未成功工作从前主线程将处于阻塞状态,等到异步线程截至获取计算结果后,主线程技艺三番五次做事,那显然不能够体现出多线程的优势。此时得以能够利用IAsyncResult
进步主线程的行事性质,IAsyncResult有以下成员:

当定义委托后,.NET就会自动创建一个象征该信托的类,上面能够用反射方式展示委托类的措施成员(对反射有意思味的情人能够先参考一下“.NET基础篇——反射的奥秘”)

1 public interface IAsyncResult
2 {
3     object AsyncState {get;}            //获取用户定义的对象,它限定或包含关于异步操作的信息。
4     WailHandle AsyncWaitHandle {get;}   //获取用于等待异步操作完成的 WaitHandle。
5     bool CompletedSynchronously {get;}  //获取异步操作是否同步完成的指示。
6     bool IsCompleted {get;}             //获取异步操作是否已完成的指示。
7 }

威尼斯人娱乐 33😉

由此轮询格局,使用IsCompleted属性判别异步操作是还是不是产生,那样在异步操作未成功前就足以让主线程施行别的的劳作。

 1     class Program  2     {  3         delegate void MyDelegate();  4   5         static void Main(string[] args)  6         {  7             MyDelegate delegate1 = new MyDelegate(AsyncThread);  8             //显示委托类的几个方法成员       9             var methods=delegate1.GetType().GetMethods(); 10             if (methods != null) 11                 foreach (MethodInfo info in methods) 12                     Console.WriteLine(info.Name); 13             Console.ReadKey(); 14          } 15      }
 1     class Program
 2     {
 3         delegate string MyDelegate(string name);
 4 
 5         static void Main(string[] args)
 6         {
 7             ThreadMessage("Main Thread");
 8             
 9             //建立委托
10             MyDelegate myDelegate = new MyDelegate(Hello);
11             //异步调用委托,获取计算结果
12             IAsyncResult result=myDelegate.BeginInvoke("Leslie", null, null);
13             //在异步线程未完成前执行其他工作
14             while (!result.IsCompleted)
15             {
16                 Thread.Sleep(200);      //虚拟操作
17                 Console.WriteLine("Main thead do work!");
18             }
19             string data=myDelegate.EndInvoke(result);
20             Console.WriteLine(data);
21             
22             Console.ReadKey();
23         }
24 
25         static string Hello(string name)
26         {
27             ThreadMessage("Async Thread");
28             Thread.Sleep(2000);
29             return "Hello " + name;
30         }
31 
32         static void ThreadMessage(string data)
33         {
34             string message = string.Format("{0}\n  ThreadId is:{1}",
35                    data,Thread.CurrentThread.ManagedThreadId);
36             Console.WriteLine(message);
37         }
38     }

威尼斯人娱乐 34😉

运行结果:

委托类蕴含以下多少个根本格局

威尼斯人娱乐 35

威尼斯人娱乐 36

 

威尼斯人娱乐 37😉

除此以外,也得以使用WailHandle落成一样的行事,WaitHandle里面包括有2个措施WaitOne(int
timeout),它能够剖断委托是还是不是到位职业,在劳作未产生前主线程能够持续其余工作。运营下边代码可获得与使用
IAsyncResult.IsCompleted 同样的结果,而且更简短方便 。

1     public class MyDelegate:MulticastDelegate
2     {
3         public MyDelegate(object target, int methodPtr);
4         //调用委托方法
5         public virtual void Invoke();
6         //异步委托
7         public virtual IAsyncResult BeginInvoke(AsyncCallback callback,object state);
8         public virtual void EndInvoke(IAsyncResult result);
9     }
 1 namespace Test
 2 {
 3     class Program
 4     {
 5         delegate string MyDelegate(string name);
 6 
 7         static void Main(string[] args)
 8         {
 9             ThreadMessage("Main Thread");
10             
11             //建立委托
12             MyDelegate myDelegate = new MyDelegate(Hello);
13  
14             //异步调用委托,获取计算结果
15             IAsyncResult result=myDelegate.BeginInvoke("Leslie", null, null);
16             
17             while (!result.AsyncWaitHandle.WaitOne(200))
18             {
19                 Console.WriteLine("Main thead do work!");
20             }
21             string data=myDelegate.EndInvoke(result);
22             Console.WriteLine(data);
23             
24             Console.ReadKey();
25         }
26 
27         static string Hello(string name)
28         {
29             ThreadMessage("Async Thread");
30             Thread.Sleep(2000);
31             return "Hello " + name;
32         }
33 
34         static void ThreadMessage(string data)
35         {
36             string message = string.Format("{0}\n  ThreadId is:{1}",
37                    data,Thread.CurrentThread.ManagedThreadId);
38             Console.WriteLine(message);
39         }
40     }

威尼斯人娱乐 38😉

当要监视多少个运维目标的时候,使用IAsyncResult.WaitHandle.WaitOne可就派不上用场了。
辛亏.NET为WaitHandle准备了其它四个静态方法:WaitAny(waitHandle[],
int)与WaitAll (waitHandle[] , int)。
内部WaitAll在伺机全部waitHandle达成后再回去3个bool值。
而WaitAny是伺机之中二个waitHandle达成后就回去贰个int,这几个int是代表已做到waitHandle在waitHandle[]中的数组索引。
上边便是选择WaitAll的例子,运营结果与行使 IAsyncResult.IsCompleted
一样。

当调用Invoke()方法时,对应此委托的持有办法都会被实施。而BeginInvoke与EndInvoke则援救委托方法的异步调用,由BeginInvoke运行的线程都属于CLPAJERO线程池中的工作者线程,在底下将详细表达。

 1     class Program
 2     {
 3         delegate string MyDelegate(string name);
 4 
 5         static void Main(string[] args)
 6         {
 7             ThreadMessage("Main Thread");
 8             
 9             //建立委托
10             MyDelegate myDelegate = new MyDelegate(Hello);
11  
12             //异步调用委托,获取计算结果
13             IAsyncResult result=myDelegate.BeginInvoke("Leslie", null, null);
14 
15             //此处可加入多个检测对象
16             WaitHandle[] waitHandleList = new WaitHandle[] { result.AsyncWaitHandle,........ };
17             while (!WaitHandle.WaitAll(waitHandleList,200))
18             {
19                 Console.WriteLine("Main thead do work!");
20             }
21             string data=myDelegate.EndInvoke(result);
22             Console.WriteLine(data);
23             
24             Console.ReadKey();
25         }
26 
27         static string Hello(string name)
28         {
29             ThreadMessage("Async Thread");
30             Thread.Sleep(2000);
31             return "Hello " + name;
32         }
33 
34         static void ThreadMessage(string data)
35         {
36             string message = string.Format("{0}\n  ThreadId is:{1}",
37                    data,Thread.CurrentThread.ManagedThreadId);
38             Console.WriteLine(message);
39         }
40     }

 

 

四.伍  利用BeginInvoke与EndInvoke完毕异步委托方法

4.七 回调函数

率先创建2个委托对象,通过IAsyncResult BeginInvoke(string
name,AsyncCallback callback,object state) 异步调用委托方法,BeginInvoke
方法除最终的五个参数外,其余参数都以与措施参数相呼应的。通过 BeginInvoke
方法将回来一个兑现了 System.IAsyncResult
接口的靶子,之后就能够动用EndInvoke(IAsyncResult )
方法就足以结束异步操作,获取委托的运行结果。

使用轮询格局来检查评定异步方法的气象十一分劳累,而且功用不高,有见及此,.NET为
IAsyncResult BeginInvoke(AsyncCallback ,
object)准备了三个回调函数。使用 AsyncCallback
就足以绑定多少个艺术作为回调函数,回调函数必须是带参数 IAsyncResult
且无再次回到值的不二法门: void AsycnCallbackMethod(IAsyncResult result)
。在BeginInvoke方法成功后,系统就会调用AsyncCallback所绑定的回调函数,最终回调函数中调用
XXX EndInvoke(IAsyncResult result)
就能够终结异步方法,它的归来值类型与寄托的再次来到值一致。

威尼斯人娱乐 39😉

 1     class Program
 2     {
 3         delegate string MyDelegate(string name);
 4 
 5         static void Main(string[] args)
 6         {
 7             ThreadMessage("Main Thread");
 8 
 9             //建立委托
10             MyDelegate myDelegate = new MyDelegate(Hello);
11             //异步调用委托,获取计算结果
12             myDelegate.BeginInvoke("Leslie", new AsyncCallback(Completed), null);
13             //在启动异步线程后,主线程可以继续工作而不需要等待
14             for (int n = 0; n < 6; n++)
15                 Console.WriteLine("  Main thread do work!");
16             Console.WriteLine("");
17 
18             Console.ReadKey();
19         }
20 
21         static string Hello(string name)
22         {
23             ThreadMessage("Async Thread");
24             Thread.Sleep(2000);             \\模拟异步操作
25             return "\nHello " + name;
26         }
27 
28         static void Completed(IAsyncResult result)
29         {
30             ThreadMessage("Async Completed");
31 
32             //获取委托对象,调用EndInvoke方法获取运行结果
33             AsyncResult _result = (AsyncResult)result;
34             MyDelegate myDelegate = (MyDelegate)_result.AsyncDelegate;
35             string data = myDelegate.EndInvoke(_result);
36             Console.WriteLine(data);
37         }
38 
39         static void ThreadMessage(string data)
40         {
41             string message = string.Format("{0}\n  ThreadId is:{1}",
42                    data, Thread.CurrentThread.ManagedThreadId);
43             Console.WriteLine(message);
44         }
45     }
 1     class Program  2     {  3         delegate string MyDelegate(string name);  4   5         static void Main(string[] args)  6         {  7             ThreadMessage("Main Thread");  8               9             //建立委托 10             MyDelegate myDelegate = new MyDelegate(Hello); 11             //异步调用委托,获取计算结果 12             IAsyncResult result=myDelegate.BeginInvoke("Leslie", null, null); 13             //完成主线程其他工作 14             .............  15             //等待异步方法完成,调用EndInvoke(IAsyncResult)获取运行结果 16             string data=myDelegate.EndInvoke(result); 17             Console.WriteLine(data); 18              19             Console.ReadKey(); 20         } 21  22         static string Hello(string name) 23         { 24             ThreadMessage("Async Thread"); 25             Thread.Sleep(2000);            //虚拟异步工作 26             return "Hello " + name; 27         } 28  29         //显示当前线程 30         static void ThreadMessage(string data) 31         { 32             string message = string.Format("{0}\n  ThreadId is:{1}", 33                    data,Thread.CurrentThread.ManagedThreadId); 34             Console.WriteLine(message); 35         } 36     }

能够看看,主线在调用BeginInvoke方法能够继续实行别的命令,而无需再等待了,那确实比使用轮询格局剖断异步方法是不是产生更有优势。
在异步方法推行到位后将会调用AsyncCallback所绑定的回调函数,注意一点,回调函数依旧是在异步线程中实践,那样就不会潜移默化主线程的运营,那也运用回调函数最值得青昧的地方。
在回调函数中有叁个既定的参数IAsyncResult,把IAsyncResult强制转换为AsyncResult后,就足以因此AsyncResult.AsyncDelegate
获取原委托,再使用EndInvoke方法赚取总结结果。
运转结果如下:

威尼斯人娱乐 40😉

威尼斯人娱乐 41

运维结果

纵然想为回调函数字传送送壹些外表消息,就能够动用BeginInvoke(AsyncCallback,object)的末段四个参数object,它同意外部向回调函数输入任何类型的参数。只必要在回调函数中应用
AsyncResult.AsyncState 就足以获得object对象。

威尼斯人娱乐 42

 1     class Program
 2     {
 3         public class Person
 4         {
 5             public string Name;
 6             public int Age;
 7         }
 8 
 9         delegate string MyDelegate(string name);
10 
11         static void Main(string[] args)
12         {
13             ThreadMessage("Main Thread");
14 
15             //建立委托
16             MyDelegate myDelegate = new MyDelegate(Hello);
17             
18             //建立Person对象
19             Person person = new Person();
20             person.Name = "Elva";
21             person.Age = 27;
22             
23             //异步调用委托,输入参数对象person, 获取计算结果
24             myDelegate.BeginInvoke("Leslie", new AsyncCallback(Completed), person);            
25           
26             //在启动异步线程后,主线程可以继续工作而不需要等待
27             for (int n = 0; n < 6; n++)
28                 Console.WriteLine("  Main thread do work!");
29             Console.WriteLine("");
30 
31             Console.ReadKey();
32         }
33 
34         static string Hello(string name)
35         {
36             ThreadMessage("Async Thread");
37             Thread.Sleep(2000);
38             return "\nHello " + name;
39         }
40 
41         static void Completed(IAsyncResult result)
42         {
43             ThreadMessage("Async Completed");
44 
45             //获取委托对象,调用EndInvoke方法获取运行结果
46             AsyncResult _result = (AsyncResult)result;
47             MyDelegate myDelegate = (MyDelegate)_result.AsyncDelegate;
48             string data = myDelegate.EndInvoke(_result);
49             //获取Person对象
50             Person person = (Person)result.AsyncState;
51             string message = person.Name + "'s age is " + person.Age.ToString();
52 
53             Console.WriteLine(data+"\n"+message);
54         }
55 
56         static void ThreadMessage(string data)
57         {
58             string message = string.Format("{0}\n  ThreadId is:{1}",
59                    data, Thread.CurrentThread.ManagedThreadId);
60             Console.WriteLine(message);
61         }
62     }

 

运作结果:

4.6  善用IAsyncResult

威尼斯人娱乐 43

在上述例子中能够望见,假诺在利用myDelegate.BeginInvoke后立马调用myDelegate.EndInvoke,那在异步线程未成功工作从前主线程将处于阻塞状态,等到异步线程结束获取总括结果后,主线程技术一而再职业,那肯定不或然显示出多线程的优势。此时得以优秀利用IAsyncResult
提升主线程的劳作性质,IAsyncResult有以下成员:

 

威尼斯人娱乐 44😉

关于I/O线程、SqlCommand二十多线程查询、PLINQ、定期器与锁的剧情就要C#汇总揭秘——细说10二线程(下)中详尽介绍。
对 .NET 开垦有乐趣的仇敌欢迎参预QQ群:230564952
共同研究 !

1 public interface IAsyncResult
2 {
3     object AsyncState {get;}            //获取用户定义的对象,它限定或包含关于异步操作的信息。
4     WailHandle AsyncWaitHandle {get;}   //获取用于等待异步操作完成的 WaitHandle。
5     bool CompletedSynchronously {get;}  //获取异步操作是否同步完成的指示。
6     bool IsCompleted {get;}             //获取异步操作是否已完成的指示。
7 }

重回目录

威尼斯人娱乐 45😉

C#总结揭秘

透过轮询情势,使用IsCompleted属性剖断异步操作是还是不是成功,那样在异步操作未到位前就能够让主线程施行别的的干活。

通过修改注册表建立Windows自定义协议
Entity Framework
并发处理详解

细说过程、应用程序域与上下文

细说10二线程(上)

威尼斯人娱乐 46😉

细说二十八线程(下)
细说事务 浓密剖析委托与事件

 1     class Program  2     {  3         delegate string MyDelegate(string name);  4   5         static void Main(string[] args)  6         {  7             ThreadMessage("Main Thread");  8               9             //建立委托 10             MyDelegate myDelegate = new MyDelegate(Hello); 11             //异步调用委托,获取计算结果 12             IAsyncResult result=myDelegate.BeginInvoke("Leslie", null, null); 13             //在异步线程未完成前执行其他工作 14             while (!result.IsCompleted) 15             { 16                 Thread.Sleep(200);      //虚拟操作 17                 Console.WriteLine("Main thead do work!"); 18             } 19             string data=myDelegate.EndInvoke(result); 20             Console.WriteLine(data); 21              22             Console.ReadKey(); 23         } 24  25         static string Hello(string name) 26         { 27             ThreadMessage("Async Thread"); 28             Thread.Sleep(2000); 29             return "Hello " + name; 30         } 31  32         static void ThreadMessage(string data) 33         { 34             string message = string.Format("{0}\n  ThreadId is:{1}", 35                    data,Thread.CurrentThread.ManagedThreadId); 36             Console.WriteLine(message); 37         } 38     }

 

威尼斯人娱乐 47😉

小编:风尘浪子
http://www.cnblogs.com/leslies2/archive/2012/02/07/2310495.html

运行结果:

原创小说,转发时请表明笔者及出处

威尼斯人娱乐 48

 

 

除此以外,也得以运用WailHandle完毕一样的行事,WaitHandle里面包蕴有3个措施WaitOne(int
timeout),它能够判断委托是或不是到位工作,在劳作未形成前主线程可以持续别的职业。运转上边代码可获得与使用
IAsyncResult.IsCompleted 一样的结果,而且更简短方便 。

威尼斯人娱乐 49😉

 1 namespace Test
 2 {
 3     class Program
 4     {
 5         delegate string MyDelegate(string name);
 6 
 7         static void Main(string[] args)
 8         {
 9             ThreadMessage("Main Thread");
10             
11             //建立委托
12             MyDelegate myDelegate = new MyDelegate(Hello);
13  
14             //异步调用委托,获取计算结果
15             IAsyncResult result=myDelegate.BeginInvoke("Leslie", null, null);
16             
17             while (!result.AsyncWaitHandle.WaitOne(200))
18             {
19                 Console.WriteLine("Main thead do work!");
20             }
21             string data=myDelegate.EndInvoke(result);
22             Console.WriteLine(data);
23             
24             Console.ReadKey();
25         }
26 
27         static string Hello(string name)
28         {
29             ThreadMessage("Async Thread");
30             Thread.Sleep(2000);
31             return "Hello " + name;
32         }
33 
34         static void ThreadMessage(string data)
35         {
36             string message = string.Format("{0}\n  ThreadId is:{1}",
37                    data,Thread.CurrentThread.ManagedThreadId);
38             Console.WriteLine(message);
39         }
40     }

威尼斯人娱乐 50😉

当要监视八个运维目的的时候,使用IAsyncResult.WaitHandle.WaitOne可就派不上用场了。
幸好.NET为WaitHandle准备了此外多个静态方法:WaitAny(waitHandle[],
int)与WaitAll (waitHandle[] , int)。
个中WaitAll在等候全部waitHandle实现后再回来3个bool值。
而WaitAny是等待之中贰个waitHandle完毕后就回去1个int,那个int是代表已做到waitHandle在waitHandle[]中的数组索引。
上面就是选用WaitAll的事例,运营结果与运用 IAsyncResult.IsCompleted
同样。

威尼斯人娱乐 51😉

 1     class Program  2     {  3         delegate string MyDelegate(string name);  4   5         static void Main(string[] args)  6         {  7             ThreadMessage("Main Thread");  8               9             //建立委托 10             MyDelegate myDelegate = new MyDelegate(Hello); 11   12             //异步调用委托,获取计算结果 13             IAsyncResult result=myDelegate.BeginInvoke("Leslie", null, null); 14  15             //此处可加入多个检测对象 16             WaitHandle[] waitHandleList = new WaitHandle[] { result.AsyncWaitHandle,........ }; 17             while (!WaitHandle.WaitAll(waitHandleList,200)) 18             { 19                 Console.WriteLine("Main thead do work!"); 20             } 21             string data=myDelegate.EndInvoke(result); 22             Console.WriteLine(data); 23              24             Console.ReadKey(); 25         } 26  27         static string Hello(string name) 28         { 29             ThreadMessage("Async Thread"); 30             Thread.Sleep(2000); 31             return "Hello " + name; 32         } 33  34         static void ThreadMessage(string data) 35         { 36             string message = string.Format("{0}\n  ThreadId is:{1}", 37                    data,Thread.CurrentThread.ManagedThreadId); 38             Console.WriteLine(message); 39         } 40     }

威尼斯人娱乐 52😉

 

四.七 回调函数

利用轮询格局来检查实验异步方法的气象不行费劲,而且效用不高,有见及此,.NET为
IAsyncResult BeginInvoke(AsyncCallback ,
object)准备了3个回调函数。使用 AsyncCallback
就能够绑定三个主意作为回调函数,回调函数必须是带参数 IAsyncResult
且无重返值的格局: void AsycnCallbackMethod(IAsyncResult result)
。在BeginInvoke方法成功后,系统就会调用AsyncCallback所绑定的回调函数,最终回调函数中调用
XXX EndInvoke(IAsyncResult result)
就能够终结异步方法,它的归来值类型与寄托的重回值壹致。

威尼斯人娱乐 53😉

 1     class Program
 2     {
 3         delegate string MyDelegate(string name);
 4 
 5         static void Main(string[] args)
 6         {
 7             ThreadMessage("Main Thread");
 8 
 9             //建立委托
10             MyDelegate myDelegate = new MyDelegate(Hello);
11             //异步调用委托,获取计算结果
12             myDelegate.BeginInvoke("Leslie", new AsyncCallback(Completed), null);
13             //在启动异步线程后,主线程可以继续工作而不需要等待
14             for (int n = 0; n < 6; n++)
15                 Console.WriteLine("  Main thread do work!");
16             Console.WriteLine("");
17 
18             Console.ReadKey();
19         }
20 
21         static string Hello(string name)
22         {
23             ThreadMessage("Async Thread");
24             Thread.Sleep(2000);             \\模拟异步操作
25             return "\nHello " + name;
26         }
27 
28         static void Completed(IAsyncResult result)
29         {
30             ThreadMessage("Async Completed");
31 
32             //获取委托对象,调用EndInvoke方法获取运行结果
33             AsyncResult _result = (AsyncResult)result;
34             MyDelegate myDelegate = (MyDelegate)_result.AsyncDelegate;
35             string data = myDelegate.EndInvoke(_result);
36             Console.WriteLine(data);
37         }
38 
39         static void ThreadMessage(string data)
40         {
41             string message = string.Format("{0}\n  ThreadId is:{1}",
42                    data, Thread.CurrentThread.ManagedThreadId);
43             Console.WriteLine(message);
44         }
45     }

威尼斯人娱乐 54😉

能够看来,主线在调用BeginInvoke方法能够继续实践别的命令,而无需再伺机了,那如实比使用轮询方式判别异步方法是或不是产生更有优势。
在异步方法推行到位后将会调用AsyncCallback所绑定的回调函数,注意一点,回调函数照旧是在异步线程中实行,那样就不会影响主线程的运维,那也采纳回调函数最值得青昧的地点。
在回调函数中有一个既定的参数IAsyncResult,把IAsyncResult强制调换为AsyncResult后,就能够通过
AsyncResult.AsyncDelegate 获取原委托,再使用EndInvoke方法得到计算结果。
运转结果如下:

威尼斯人娱乐 55

只要想为回调函数字传送送一些表面音讯,就能够动用BeginInvoke(AsyncCallback,object)的末段二个参数object,它同意外部向回调函数输入任何类型的参数。只要求在回调函数中应用
AsyncResult.AsyncState 就足以获得object对象。

威尼斯人娱乐 56😉

 1     class Program  2     {  3         public class Person  4         {  5             public string Name;  6             public int Age;  7         }  8   9         delegate string MyDelegate(string name); 10  11         static void Main(string[] args) 12         { 13             ThreadMessage("Main Thread"); 14  15             //建立委托 16             MyDelegate myDelegate = new MyDelegate(Hello); 17              18             //建立Person对象 19             Person person = new Person(); 20             person.Name = "Elva"; 21             person.Age = 27; 22              23             //异步调用委托,输入参数对象person, 获取计算结果 24             myDelegate.BeginInvoke("Leslie", new AsyncCallback(Completed), person);             25            26             //在启动异步线程后,主线程可以继续工作而不需要等待 27             for (int n = 0; n < 6; n++) 28                 Console.WriteLine("  Main thread do work!"); 29             Console.WriteLine(""); 30  31             Console.ReadKey(); 32         } 33  34         static string Hello(string name) 35         { 36             ThreadMessage("Async Thread"); 37             Thread.Sleep(2000); 38             return "\nHello " + name; 39         } 40  41         static void Completed(IAsyncResult result) 42         { 43             ThreadMessage("Async Completed"); 44  45             //获取委托对象,调用EndInvoke方法获取运行结果 46             AsyncResult _result = (AsyncResult)result; 47             MyDelegate myDelegate = (MyDelegate)_result.AsyncDelegate; 48             string data = myDelegate.EndInvoke(_result); 49             //获取Person对象 50             Person person = (Person)result.AsyncState; 51             string message = person.Name + "'s age is " + person.Age.ToString(); 52  53             Console.WriteLine(data+"\n"+message); 54         } 55  56         static void ThreadMessage(string data) 57         { 58             string message = string.Format("{0}\n  ThreadId is:{1}", 59                    data, Thread.CurrentThread.ManagedThreadId); 60             Console.WriteLine(message); 61         } 62     }

威尼斯人娱乐 57😉

运转结果:

威尼斯人娱乐 58

 

关于I/O线程、SqlCommand多线程查询、PLINQ、定期器与锁的剧情将要C#综合揭秘——细说八线程(下)中详尽介绍。
对 .NET 开荒风乐趣的恋人欢迎插足QQ群:230564952
共同钻探 !

归来目录

C#综述揭秘

通过改变注册表建立Windows自定义协议
Entity Framework
并发处理详解
前述进度、应用程序域与上下文

细说多线程(上)

前述八线程(下) 前述事务深切剖析委托与事件

 

小编:风尘浪子 http://www.cnblogs.com/leslies2/archive/2012/02/07/2310495.html

原创小说,转发时请申明笔者及出处

 

 

 

分类:
C#综合揭秘

相关文章