C程序设计 第七章 线程.ppt

上传人:s****8 文档编号:69346905 上传时间:2023-01-02 格式:PPT 页数:29 大小:318.50KB
返回 下载 相关 举报
C程序设计 第七章 线程.ppt_第1页
第1页 / 共29页
C程序设计 第七章 线程.ppt_第2页
第2页 / 共29页
点击查看更多>>
资源描述

《C程序设计 第七章 线程.ppt》由会员分享,可在线阅读,更多相关《C程序设计 第七章 线程.ppt(29页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、C#程序设计与案例教程 清华大学出版社 第七章第七章 线程线程线程是程序运行的基本单元。多线程编程线程是程序运行的基本单元。多线程编程就是将程序任务分成几个并行的子任务,就是将程序任务分成几个并行的子任务,各个子任务相对独立地并发执行,这样可各个子任务相对独立地并发执行,这样可以提高程序的性能和效率。以提高程序的性能和效率。C#C#语言提供语言提供了内置的多线程机制。了内置的多线程机制。1 1版权所有版权所有C#程序设计与案例教程 清华大学出版社 目录n n线程及其创建线程及其创建n n线程的基本控制线程的基本控制n n线程同步线程同步n n线程通信线程通信n n线程池线程池2 2版权所有版权

2、所有C#程序设计与案例教程 清华大学出版社 7.1 线程及其创建线程及其创建n n线程与进程相似,是一段完成某个特定功能的线程与进程相似,是一段完成某个特定功能的代码,是程序中的一个执行流;但与进程不同代码,是程序中的一个执行流;但与进程不同的是,同一个类的多个线程是共享一块内存空的是,同一个类的多个线程是共享一块内存空间和一组系统资源,而线程本身的数据通常只间和一组系统资源,而线程本身的数据通常只有微处理器的寄存器数据,以及一个供程序执有微处理器的寄存器数据,以及一个供程序执行时使用的堆栈。所以系统在产生一个线程,行时使用的堆栈。所以系统在产生一个线程,或者在各个线程之间切换时,负担要比进程

3、小或者在各个线程之间切换时,负担要比进程小的多,正因如此,线程被称为轻量级进程。的多,正因如此,线程被称为轻量级进程。3 3版权所有版权所有C#程序设计与案例教程 清华大学出版社 7.1.1线程与进程的比较线程与进程的比较(1 1)基于进程的特点是允许计算机同时运行两)基于进程的特点是允许计算机同时运行两)基于进程的特点是允许计算机同时运行两)基于进程的特点是允许计算机同时运行两个或更多的程序。个或更多的程序。个或更多的程序。个或更多的程序。(2 2)基于线程的多任务处理环境中,线程是最)基于线程的多任务处理环境中,线程是最)基于线程的多任务处理环境中,线程是最)基于线程的多任务处理环境中,线

4、程是最小的处理单位。小的处理单位。小的处理单位。小的处理单位。(3 3)多个进程的内部数据和状态都是完全独立)多个进程的内部数据和状态都是完全独立)多个进程的内部数据和状态都是完全独立)多个进程的内部数据和状态都是完全独立的,而多线程是共享一块内存空间和一组系的,而多线程是共享一块内存空间和一组系的,而多线程是共享一块内存空间和一组系的,而多线程是共享一块内存空间和一组系 统统统统资源资源资源资源,有可能互相影响。有可能互相影响。有可能互相影响。有可能互相影响。(4 4)线程本身的数据通常只有寄存器数据,以)线程本身的数据通常只有寄存器数据,以)线程本身的数据通常只有寄存器数据,以)线程本身的

5、数据通常只有寄存器数据,以及一个程序执行时使用的堆栈,所以线程的切及一个程序执行时使用的堆栈,所以线程的切及一个程序执行时使用的堆栈,所以线程的切及一个程序执行时使用的堆栈,所以线程的切换比进程切换的负担要小。换比进程切换的负担要小。换比进程切换的负担要小。换比进程切换的负担要小。4 4版权所有版权所有C#程序设计与案例教程 清华大学出版社 7.1.27.1.2线程的优点线程的优点线程的优点线程的优点 有多个线程的进程能够用线程管理互斥的任务,比如提有多个线程的进程能够用线程管理互斥的任务,比如提供用户一个界面和完成后台计算。创建一个多线程的供用户一个界面和完成后台计算。创建一个多线程的进程能

6、够方便地让程序并发执行几个类似的或相同的进程能够方便地让程序并发执行几个类似的或相同的任务。任务。例如,单个应用程序域可以使用多个线程来完成以下任例如,单个应用程序域可以使用多个线程来完成以下任务:务:(1 1)通过网络与)通过网络与 Web Web 服务器和数据库进行通信。服务器和数据库进行通信。(2 2)执行占用大量时间的操作。)执行占用大量时间的操作。(3 3)区分具有不同优先级的任务。例如,高优先级线程)区分具有不同优先级的任务。例如,高优先级线程管理时间关键的任务,低优先级线程执行其他任务。管理时间关键的任务,低优先级线程执行其他任务。(4 4)使用户界面可以在将时间分配给后台任务时

7、仍能快)使用户界面可以在将时间分配给后台任务时仍能快速作出响应。速作出响应。5 5版权所有版权所有C#程序设计与案例教程 清华大学出版社 7.1.37.1.3建立线程建立线程创建线程的基本步骤如下:创建线程的基本步骤如下:(1 1)声明该线程。)声明该线程。System.Threading.ThreadSystem.Threading.Thread myThreadmyThread;(2 2)用线程起始点的适当委托实例化该线程。在)用线程起始点的适当委托实例化该线程。在 C#C#中中创建新的创建新的ThreadStartThreadStart 对象。对象。myThreadmyThread=ne

8、w =new System.Threading.Thread(newSystem.Threading.Thread(new System.Threading.ThreadStSystem.Threading.ThreadStart(myStartingMethodart(myStartingMethod););(3 3)调用)调用 Thread.StartThread.Start()()方法启动线程。方法启动线程。myThread.StartmyThread.Start();();6 6版权所有版权所有C#程序设计与案例教程 清华大学出版社 【案例案例案例案例7-17-1】随机画圆。随机画圆。

9、n n本案例是一个随机画圆本案例是一个随机画圆的程序。每次画的位置、的程序。每次画的位置、大小、颜色都是随机的。大小、颜色都是随机的。7 7版权所有版权所有C#程序设计与案例教程 清华大学出版社 7.2 线程的基本控制线程的基本控制n n线程从创建到灭亡主要经历五种状态,借助线程从创建到灭亡主要经历五种状态,借助ThreadThread类所提供的方法,我们可以实现这些状类所提供的方法,我们可以实现这些状态之间的转换,从而达到对线程的控制。通过态之间的转换,从而达到对线程的控制。通过本节内容重点掌握线程的基本控制方法、线程本节内容重点掌握线程的基本控制方法、线程的优先级及其他有关概念。的优先级及

10、其他有关概念。8 8版权所有版权所有C#程序设计与案例教程 清华大学出版社 7.2.1线程的状态n n一个线程从被创建到停止执行要经历一个完整一个线程从被创建到停止执行要经历一个完整的生命周期。在这个生命周期中线程处于不同的生命周期。在这个生命周期中线程处于不同的状态。线程的状态用来表明线程的活动情况的状态。线程的状态用来表明线程的活动情况及线程在当前状态中能够完成的功能。线程的及线程在当前状态中能够完成的功能。线程的生命周期有五种状态。生命周期有五种状态。9 9版权所有版权所有C#程序设计与案例教程 清华大学出版社 7.2.2 Thread7.2.2 Thread类和线程控制类和线程控制1

11、1ThreadThread主要的属性主要的属性主要的属性主要的属性(1 1)CurrentThreadCurrentThread:获取当前正在运行的线程。获取当前正在运行的线程。(2 2)IsAliveIsAlive:获取一个值获取一个值,该值指示当前线程的执行状该值指示当前线程的执行状态。态。(3 3)IsBackgroundIsBackground:获取或设置一个值,该值指示某个:获取或设置一个值,该值指示某个线程是否为后台线程。线程是否为后台线程。(4 4)IsThreadPoolThreadIsThreadPoolThread:获取一个值,该值指示线程:获取一个值,该值指示线程是否属于

12、托管线程池。是否属于托管线程池。(5 5)NameName:获取或设置线程的名称。:获取或设置线程的名称。(6 6)PriorityPriority:获取或设置一个值,该值指示线程的调度:获取或设置一个值,该值指示线程的调度优先级。优先级。1010版权所有版权所有C#程序设计与案例教程 清华大学出版社 2 2ThreadThread的主要方法的主要方法的主要方法的主要方法(1 1)Abort()Abort():在调用此方法的线程上引发在调用此方法的线程上引发 ThreadAbortExceptionThreadAbortException,以开始终止此线程的过程。调以开始终止此线程的过程。调用

13、此方法通常会终止线程。用此方法通常会终止线程。(2 2)Interrupt()Interrupt():中断处于:中断处于 WaitSleepJoinWaitSleepJoin 线程状态的线线程状态的线程。程。(3 3)Join()Join():阻塞调用线程,直到某个线程终止时为止。:阻塞调用线程,直到某个线程终止时为止。(4 4)ResetAbortResetAbort()():取消为当前线程请求的:取消为当前线程请求的 AbortAbort。(5 5)Resume()Resume():继续已挂起的线程。:继续已挂起的线程。(6 6)Sleep(intSleep(int):将当前线程阻塞指定的

14、毫秒数。:将当前线程阻塞指定的毫秒数。(7 7)Start()Start():导致操作系统将当前实例的状态更改为:导致操作系统将当前实例的状态更改为 ThreadState.RunningThreadState.Running。(8 8)Suspend()Suspend():挂起线程,或者如果线程已挂起,则:挂起线程,或者如果线程已挂起,则不起作用。不起作用。(9 9)ThreadStateThreadState()():获取一个值,该值包含当前线程的:获取一个值,该值包含当前线程的状态。状态。1111版权所有版权所有C#程序设计与案例教程 清华大学出版社 【案例案例案例案例7-27-2】图像

15、浏览程图像浏览程序。序。n n本案例是一个图像浏览本案例是一个图像浏览程序,能够自动切换图程序,能够自动切换图片,并可以通过片,并可以通过“开始开始”、“停止停止”、“暂停暂停”、“恢复恢复”、“下页下页”、“上页上页”等按钮控等按钮控制图像的浏览。制图像的浏览。1212版权所有版权所有C#程序设计与案例教程 清华大学出版社 7.3 线程同步线程同步n n在包含多个线程的应用程序中,线程间有时会在包含多个线程的应用程序中,线程间有时会共享存储空间。当两个或多个线程同时访问同共享存储空间。当两个或多个线程同时访问同一共享资源时,必然会出现冲突问题。如,一一共享资源时,必然会出现冲突问题。如,一个

16、线程可能尝试从一个文件中读取数据,而另个线程可能尝试从一个文件中读取数据,而另一个线程则尝试在同一文件中修改数据。在这一个线程则尝试在同一文件中修改数据。在这种情况下,数据可能会变的不一致。我们需要种情况下,数据可能会变的不一致。我们需要做的是允许一个线程彻底完成其任务后,再允做的是允许一个线程彻底完成其任务后,再允许下一个线程执行。必须保证一个共享资源一许下一个线程执行。必须保证一个共享资源一次只被一个线程使用。实现此目的的过程称为次只被一个线程使用。实现此目的的过程称为同步同步同步同步。1313版权所有版权所有C#程序设计与案例教程 清华大学出版社 7.3.1 使用lock()语句n n多

17、个线程共享资源时,多个线程共享资源时,C#C#提供了提供了locklock,它可以,它可以把一段代码定义为互斥段,互斥段在一个时刻把一段代码定义为互斥段,互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须内只允许一个线程进入执行,而其他线程必须等待。基本的格式为:等待。基本的格式为:locklock(对象或类对象或类)语句块语句块1414版权所有版权所有C#程序设计与案例教程 清华大学出版社 【案例案例案例案例7-37-3】模拟取款程模拟取款程序。序。n n本案例模拟取款程序,本案例模拟取款程序,有一笔存款,三个人同有一笔存款,三个人同时在取钱,每个人可取时在取钱,每个人可取5 5次,每

18、次当取款时,次,每次当取款时,若数额超过现有的存款若数额超过现有的存款额,那么取款被拒绝。额,那么取款被拒绝。要保证一个人正在取款要保证一个人正在取款时,另一个人不能取。时,另一个人不能取。存款的数额永远不为负。存款的数额永远不为负。1515版权所有版权所有C#程序设计与案例教程 清华大学出版社 7.3.2 Monitor7.3.2 Monitor类类 在实现线程同步时,可以使用在实现线程同步时,可以使用MonitorMonitor类。该类通过向类。该类通过向单个线程授予对象锁来控制对对象的访问。对象锁提单个线程授予对象锁来控制对对象的访问。对象锁提供限制访问代码块(通常称为临界区)的能力。当

19、一供限制访问代码块(通常称为临界区)的能力。当一个线程拥有对象的锁时,其他任何线程都不能获取该个线程拥有对象的锁时,其他任何线程都不能获取该锁。锁。MonitorMonitor具有以下功能具有以下功能:(1 1)它根据需要与某个对象相关联。)它根据需要与某个对象相关联。(2 2)它是未绑定的,也就是说可以直接从任何上下文调)它是未绑定的,也就是说可以直接从任何上下文调用它。用它。(3 3)不能创建)不能创建MonitorMonitor类的实例。类的实例。(4 4)将为每个同步对象来维护以下信息:)将为每个同步对象来维护以下信息:对当前持有锁的线程的引用。对当前持有锁的线程的引用。对就绪队列的引

20、用,它包含准备获取锁的线程。对就绪队列的引用,它包含准备获取锁的线程。对等待队列的引用,它包含正在等待锁定对象状态变化对等待队列的引用,它包含正在等待锁定对象状态变化通知的线程。通知的线程。1616版权所有版权所有C#程序设计与案例教程 清华大学出版社 常用的方法有:常用的方法有:(1 1)Enter(),Enter(),TryEnterTryEnter()():获取对象锁。此操作同样会标记:获取对象锁。此操作同样会标记临界区的开头。其他任何线程都不能进入临界区,除非它临界区的开头。其他任何线程都不能进入临界区,除非它使用其他锁定对象执行临界区中的指令。使用其他锁定对象执行临界区中的指令。(2

21、 2)Wait()Wait():释放对象上的锁以便允许其他线程锁定和访问:释放对象上的锁以便允许其他线程锁定和访问该对象。在其他线程访问对象时,调用线程将等待。脉冲该对象。在其他线程访问对象时,调用线程将等待。脉冲信号用于通知等待线程有关对象状态的更改。信号用于通知等待线程有关对象状态的更改。(3 3)Pulse()Pulse(),PulseAllPulseAll()():向一个或多个等待线程发送信号。:向一个或多个等待线程发送信号。该信号通知等待线程锁定对象的状态已更改,并且锁的所该信号通知等待线程锁定对象的状态已更改,并且锁的所有者准备释放该锁。等待线程被放置在对象的就绪队列中有者准备释放

22、该锁。等待线程被放置在对象的就绪队列中以便它可以最后接收对象锁。一旦线程拥有了锁,它就可以便它可以最后接收对象锁。一旦线程拥有了锁,它就可以检查对象的新状态以查看是否达到所需状态。以检查对象的新状态以查看是否达到所需状态。(4 4)Exit()Exit():释放对象上的锁。此操作还标记受锁定对象保:释放对象上的锁。此操作还标记受锁定对象保护的临界区的结尾。护的临界区的结尾。1717版权所有版权所有C#程序设计与案例教程 清华大学出版社 【案例案例案例案例7-47-4】模拟调动程模拟调动程序。序。n n本案例是个模拟调度的本案例是个模拟调度的程序。对给定数量的车程序。对给定数量的车皮进行调度,图

23、(皮进行调度,图(a a)为没有使用同步控制的为没有使用同步控制的运行结果,图(运行结果,图(b b)为)为使用同步控制的运行结使用同步控制的运行结果。果。1818版权所有版权所有C#程序设计与案例教程 清华大学出版社 7.3.3 Interlocked类类此类为多个线程共享的变量提供原子操作。主要此类为多个线程共享的变量提供原子操作。主要有如下方法:有如下方法:(1 1)CompareExchangeCompareExchange()():比较两个值是否相:比较两个值是否相等,如果相等,则替换其中一个值。等,如果相等,则替换其中一个值。(2 2)Decrement()Decrement():

24、以原子操作的形式递减指定:以原子操作的形式递减指定变量的值并存储结果。变量的值并存储结果。(3 3)Exchange()Exchange():以原子操作的形式将变量设:以原子操作的形式将变量设置为指定的值。置为指定的值。(4 4)Increment()Increment():以原子操作的形式递增指定:以原子操作的形式递增指定变量的值并存储结果。变量的值并存储结果。1919版权所有版权所有C#程序设计与案例教程 清华大学出版社 7.3.4 Mutex类类n nMutexMutex类用于线程或线程间的同步原语操作。类用于线程或线程间的同步原语操作。当两个或更多线程需要同时访问一个共享资源当两个或更

25、多线程需要同时访问一个共享资源时,系统需要使用同步机制来确保一次只有一时,系统需要使用同步机制来确保一次只有一个线程使用该资源。个线程使用该资源。MutexMutex是同步原语,它只是同步原语,它只向一个线程授予对共享资源的独占访问权。如向一个线程授予对共享资源的独占访问权。如果一个线程获取了互斥体,则要获取该互斥体果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放的第二个线程将被挂起,直到第一个线程释放该互斥体。该互斥体。2020版权所有版权所有C#程序设计与案例教程 清华大学出版社 1 1MutexMutex的构造函数的构造函数的构造函数的构造函数(1 1)p

26、ublic public MutexMutex()():使用默认属性初始化:使用默认属性初始化 MutexMutex类的新实类的新实例。例。(2 2)public public Mutex(boolMutex(bool):使用指示调用线程是否应拥有互:使用指示调用线程是否应拥有互斥体的初始所属权的布尔值来初始化斥体的初始所属权的布尔值来初始化 MutexMutex类的新实例。类的新实例。(3 3)public public Mutex(boolMutex(bool,string),string):使用指示调用线程是否应:使用指示调用线程是否应拥有互斥体的初始所属权的布尔值和作为互斥体名称的字拥

27、有互斥体的初始所属权的布尔值和作为互斥体名称的字符串来初始化符串来初始化 MutexMutex类的新实例。类的新实例。(4 4)public public Mutex(boolMutex(bool,string,string,boolbool):使用指示调用线程是:使用指示调用线程是否应拥有互斥体的初始所属权的布尔值、作为互斥体名称否应拥有互斥体的初始所属权的布尔值、作为互斥体名称的字符串以及在方法返回时指示调用线程是否已被授予互的字符串以及在方法返回时指示调用线程是否已被授予互斥体的初始所属权的布尔值来初始化斥体的初始所属权的布尔值来初始化 MutexMutex类的新实例。类的新实例。212

28、1版权所有版权所有C#程序设计与案例教程 清华大学出版社 2 2MutexMutex的主要方法的主要方法的主要方法的主要方法(1 1)Close()Close():在派生类中被重写时,释放由当:在派生类中被重写时,释放由当前前WaitHandleWaitHandle持有的所有资源。持有的所有资源。(2 2)ReleaseMutexReleaseMutex()():释放:释放 MutexMutex一次。一次。(3 3)WaitOneWaitOne()():阻塞当前线程,直到当前的:阻塞当前线程,直到当前的WaitHandleWaitHandle收到信号。收到信号。2222版权所有版权所有C#程序

29、设计与案例教程 清华大学出版社 7.4线程通信线程通信7.4.1 使用Monitor实现线程通信n nLockLock语句与语句与MonitorMonitor类配合,不仅可以实现线程类配合,不仅可以实现线程同步,而且借助同步,而且借助MonitorMonitor类的类的Wait()Wait()、PulsePulse()、()、PulseAllPulseAll()()方法还可以进行线程通信。方法还可以进行线程通信。2323版权所有版权所有C#程序设计与案例教程 清华大学出版社 【案例案例案例案例6-56-5】吃苹果。吃苹果。n n本案例是一个模拟吃苹果的本案例是一个模拟吃苹果的程序。爸爸、妈妈不

30、断往盘程序。爸爸、妈妈不断往盘子里放苹果,三个孩子:老子里放苹果,三个孩子:老大、老二和老三不断地从盘大、老二和老三不断地从盘子里取苹果吃。五个线程需子里取苹果吃。五个线程需要同步执行,并且要互相协要同步执行,并且要互相协调。爸爸和妈妈放苹果时,调。爸爸和妈妈放苹果时,盘子里要有地方,而且两个盘子里要有地方,而且两个人不能同时放。三个孩子取人不能同时放。三个孩子取苹果时,盘子里要有苹果,苹果时,盘子里要有苹果,而且也不能同时取。此外,而且也不能同时取。此外,三个孩子因吃苹果速度不同,三个孩子因吃苹果速度不同,取苹果的频率不一样,又因取苹果的频率不一样,又因大小不同,有不同的优先级。大小不同,有

31、不同的优先级。2424版权所有版权所有C#程序设计与案例教程 清华大学出版社 7.4.2 使用AutoResetEvent类和ManualResetEvent类进行线程通信n nAutoResetEventAutoResetEvent 允许线程通过发信号互相通信。允许线程通过发信号互相通信。n nManualResetEventManualResetEvent类与类与AutoResetEventAutoResetEvent的使的使用基本类似。所不同的是,用基本类似。所不同的是,AutoResetEventAutoResetEvent 在在单个等待线程被释放后由系统自动重置为无信单个等待线程被释

32、放后由系统自动重置为无信号的状态。号的状态。2525版权所有版权所有C#程序设计与案例教程 清华大学出版社 【实例实例实例实例7-67-6】哲学家用餐。哲学家用餐。n n哲学家用餐问题是典型的线哲学家用餐问题是典型的线程序间通信的问题。五位哲程序间通信的问题。五位哲学家坐在餐桌前,他们在思学家坐在餐桌前,他们在思考并在感到饥饿时就吃东西。考并在感到饥饿时就吃东西。每两位哲学家之间只有一根每两位哲学家之间只有一根筷子,为了吃东西,一位哲筷子,为了吃东西,一位哲学家必须要用两根筷子。如学家必须要用两根筷子。如果每位哲学家拿起右筷子,果每位哲学家拿起右筷子,然后等着拿左筷子,问题就然后等着拿左筷子,

33、问题就产生了。在这种情况下,就产生了。在这种情况下,就会发生死锁。当哲学家放下会发生死锁。当哲学家放下筷子时,要通知其他等待拿筷子时,要通知其他等待拿筷子的哲学家。筷子的哲学家。2626版权所有版权所有C#程序设计与案例教程 清华大学出版社 7.5线程池 n n线程池通过对多个任务重用线程,线程创建的线程池通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。其好处是,因为开销被分摊到了多个任务上。其好处是,因为请求到达时线程已经存在,所以无意中也就消请求到达时线程已经存在,所以无意中也就消除了线程创建是所带来的延迟。这样,就可以除了线程创建是所带来的延迟。这样,就可以立即为新线程请求服

34、务,使其应用程序响应更立即为新线程请求服务,使其应用程序响应更快。而且,通过适当地调整线程池中线程数目,快。而且,通过适当地调整线程池中线程数目,也就是当请求的数目超过了规定的最大数目时,也就是当请求的数目超过了规定的最大数目时,就强制其他任何新到的请求一直等待,直到获就强制其他任何新到的请求一直等待,直到获得一个线程来处理为止,从而可以防止资源不得一个线程来处理为止,从而可以防止资源不足。足。2727版权所有版权所有C#程序设计与案例教程 清华大学出版社 n nThreadPoolThreadPool类提供一个由系统维护的线程池,可以看类提供一个由系统维护的线程池,可以看做一个线程的容器,该

35、容器需要做一个线程的容器,该容器需要Windows2000Windows2000以上版以上版本的系统支持。可以使用本的系统支持。可以使用ThreadPool.QueueUserWorkItemThreadPool.QueueUserWorkItem()()方法将线程安放在线程池里。该方法有两个重载格式:方法将线程安放在线程池里。该方法有两个重载格式:n npublic static public static boolbool QueueUserWorkItem(WaitCallbackQueueUserWorkItem(WaitCallback):将方法排入队列以便执行。此方法在有线程池线程

36、:将方法排入队列以便执行。此方法在有线程池线程变得可用时执行。变得可用时执行。n npublic static public static boolbool QueueUserWorkItem(WaitCallbackQueueUserWorkItem(WaitCallback,object)object):将方法排入队列以便执行,并指定包含该方:将方法排入队列以便执行,并指定包含该方法所用数据的对象。此方法在有线程池线程变得可用法所用数据的对象。此方法在有线程池线程变得可用时执行。时执行。2828版权所有版权所有C#程序设计与案例教程 清华大学出版社 【案例案例案例案例7-77-7】线程池使用线程池使用演示。演示。n n本案例将本案例将5 5个线程添加个线程添加到线程池,演示线程池到线程池,演示线程池自动建立线程及执行线自动建立线程及执行线程的情况。程的情况。2929版权所有版权所有

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 生活常识

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com