您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > 第6章 进程与线程开发程序设计
2010.07第6章进程与线程开发程序设计学习要点1.了解进程与线程的基本技术2.掌握C#进程应用程序开发方法3.掌握C#常用多线程互斥与同步的应用程序开发方法4.掌握C#跨线程访问控件的基本方法6.1进程与线程概述1.进程Windows是一个多任务的系统,它能够同时运行多个程序,其中的每一个正在运行的程序就称为一个“进程”。Windows2000及其以上版本,可以通过任务管理器查看系统当前运行的程序和进程。2.线程对于同一个进程,又可以分成若干个独立的执行流,这样的流则被称为“线程”。线程是操作系统向其分配处理器时间的基本单位,它可以独立占用处理器的时间片,同一进程中的线程可以共享其进程的资源和内存空间。每一个进程至少包含一个线程。3.并发进程和线程技术的引入,为实现系统或应用程序的并行性提供了重要的技术基础。所谓的“并行”又被称为“并发”,是指系统或应用程序同时处理多个事务的运行过程。对于单处理器的计算机系统来说,由于单个CPU在任何时刻只能执行一个线程,所以,这种计算机系统的并发,实际上是通过操作系统在各个正在执行的线程之间切换CPU,以分时处理的方式实现表面形式上的并发,只是因为其切换的速度快且处理能力强时,用户直观感觉不到而已。当然,对于多处理器的计算机系统,其多个CPU之间既有相互协作,又有独立分工,所以,它们在各自执行一个相应线程时可以互不影响,同时进行,进而实现真正意义上的并发处理。6.2进程开发技术进程与程序不同,它是程序执行时的标志,而不是程序的静态版本。用户创建一个进程后,操作系统就将程序的一个副本装入计算机中,然后启动一个线程执行该程序。尽管.NET环境中仍然使用进程和线程,但管理代码的应用程序边界是应用程序域。通用语言运行库(CLR)强制隔离应用程序域,使一个进程中可以有多个隔离的应用程序。在C#中,可通过两种方法来开发进程程序:•C#的System.Diagnostics命名空间下的Process类专门用于完成系统的进程管理任务,通过实例化一个Process类,就可以启动一个独立进程。•C#的进程组件(Process)提供了对本地和远程进程的访问功能,并启用本地进程的开始和停止功能。6.2进程开发技术开发一个利用进程控制应用程序的设计示例。通过点击相应的按钮,既能方便地打开Windows操作系统附件中的“计算器”或此前开发的“上机自测系统”,也能将它们随时关闭。【示例代码:chpt6-2\CProcess】(1)新建一个C#项目,其Windows应用程序命名为CProcess,并从“公共组件”工具箱中拖放相应控件到新建窗体Form1上。(2)按照表所示的内容,设置各控件的相应属性值。控件(Name)属性属性新值button1NamebtnCalculatorStartText启动一个计算器button2NamebtnCalculatorStopAllText关闭全部计算器button3NamebtnSelfExamStartText启动一个上机自测系统button4NamebtnSelfExamStopAllText关闭全部上机自测系统6.2进程开发技术(3)从“组件”工具箱中拖放1个Process组件到该窗体上,并将它们的Text属性分别设置为CalculatorProcess。(4)首先,从Windows操作系统的“开始”→“所有程序”→“附件”→右键点击“计算器”,打开“快捷方式”属性对话框,如图6-2所示,将其“目标”文件及其前面的“\”合并至“起始位置”之后,拷贝全部“起始位置”内容,并点击“取消”关闭计算器属性面板。利用进程控制应用程序设置进程启动信息6.2进程开发技术(5)分别编写通过C#进程组件启动和关闭计算器的相应代码。usingSystem.Diagnostics;usingSystem.Threading;//启动一个Windows计算器privatevoidbtnCalculatorStart_Click(objectsender,EventArgse){CalculatorProcess.Start();}//关闭全部已启动的Windows计算器privatevoidbtnCalculatorStopAll_Click(objectsender,EventArgse){//创建一个Process组件的数组Process[]CalculatorProcess;//将所建数组与指定进程名称(calc)的所有进程资源相关联CalculatorProcess=Process.GetProcessesByName(calc);//遍历当前启动程序中,查找包含指定名称的进程foreach(ProcessinstanceinCalculatorProcess){//终止当前进程,关闭应用程序窗体instance.CloseMainWindow();}}6.2进程开发技术(6)分别编写通过实例化一个C#的Process类,启动和关闭上机自测系统的相应代码。usingSystem.IO;//启动一个上机自测系统privatevoidbtnSelfExamStart_Click(objectsender,EventArgse){FileInfofInfo=newFileInfo(@E:\C#程序设计\教材源代码\chpt5-1\selfExam\selfExam\bin\Debug\selfExam.exe);if(fInfo.Exists){//实例一个Process类,启动一个独立进程ProcessprcsSelfExam=newProcess();//Process有一个StartInfo属性,这是ProcessStartInfo类,包括一些方法和属性//待启动的程序文件prcsSelfExam.StartInfo.FileName=fInfo.FullName;//启动进程prcsSelfExam.Start();}else{MessageBox.Show(文件:+fInfo.FullName+不存在!);}}6.2进程开发技术//关闭已启动的所有上机自测系统{//创建一个Process组件的数组Process[]SelfExamProcess;//将所建数组与指定进程名称(selfExam)的所有进程资源相关联SelfExamProcess=Process.GetProcessesByName(selfExam);//遍历当前启动程序中,查找包含指定名称的进程foreach(ProcessinstanceinSelfExamProcess){//终止当前进程,关闭应用程序窗体instance.CloseMainWindow();}}6.3线程开发基础知识1.命名空间引用.NET将关于多线程的功能定义在System.Threading命名空间中。因此,要使用多线程,必须先引用此命名空间(usingSystem.Threading;)。在这个命名空间下,包含了用于创建和控制线程的类Thread。一个Thread的实例表示一个线程,也就是一个执行序列。通过实例化一个Thread对象,就可以创建一个线程。6.3线程开发基础知识2.线程创建与控制在System.Threading.Thread类中,包含了以下几种方法,用于创建和控制线程:•创建线程在C#中使用Thread类创建线程时,只需提供线程入口即可(线程入口使程序知道该让这个线程去做什么)。线程入口是通过ThreadStart代理(delegate)来提供的,我们可以把ThreadStart理解为一个函数指针,指向线程要执行的函数,示例代码如下:Threadthread1=newThread(newThreadStart(Method1));•启动线程顾名思义,“启动线程”就是并启动一个新建的线程。当调用C#的Start()方法后,线程就开始执行ThreadStart所代表或者说指向的函数,示例代码如下:thread1.Start();其中的Method1是将要被新线程执行的函数。6.3线程开发基础知识•销毁线程因为计算机的资源是有限的,所以,当一个线程的任务完成后,如果此后将不再被使用它,就应及时释放它所占用的系统内存,也即销毁它。通过调用Abort()方法销毁一个线程。所以,为了不徒劳去销毁一个非活线程,在销毁一个线程之前通常先利用IsAlive属性来判断它是否还处于活动状态,而后再采取销毁措施,示例代码如下:if(thread1.IsAlive==true){thread1.Abort();}•休眠线程开发线程时,有时不希望它一直连续运行,而是以一定的周期运行,或者想让它延迟一段时间,以等待其他线程运行,这时可利用Sleep()方法,将“当前线程”临时终止或休眠一段时间(毫秒)。如Thread.Sleep(1000);就是让线程休眠1秒钟。6.3线程开发基础知识•挂起线程Suspend()方法用来挂起一个正在运行的线程,直到调用Resume()方法,此线程才可以继续执行。如果线程已挂起,则此方法不起作用,所以,在准备执行线程挂起操作之前,先要判断其当前是否处于运行状态,示例代码如下:if(thread1.ThreadState=ThreadState.Running){thread1.Suspend();}•恢复线程Resume()方法用来恢复已经挂起的线程,以让它继续执行,但若线程并未挂起,则此方法不会起作用,所以,在准备执行线程挂起操作之前,先要判断其当前是否处于挂起状态,示例代码如下:if(thread1.ThreadState=ThreadState.Suspended){thread1.Resume();}•终止线程Thread.Interrupt()用来终止处于Wait、Sleep或者Join状态的线程。•阻塞线程Join()用来阻塞调用线程,直到某个线程终止时为止。6.3线程开发基础知识3.Thread的公共属性属性名称说明ApartmentState获取或设置线程的单元状态CurrentContext获取线程正在执行的当前上下文CurrentCulture获取或设置线程的区域性CurrentPrincipal获取或设置线程当前负责人CurrentThread获取当前正在运行的线程CurrentUICulture获取或设置资源管理器使用的当前区域性IsAlive获取一个值,该值指示当前线程的执行状态。如果此线程已启动并且尚未正常终止或中止,则为true;否则为falseIsBackGround获取或设置一个值,该值指示某个线程是否为后台线程IsThreasPoolThread判断是否是线程池线程Name获取或设置线程名称Priority获取或设置一个值,该值指示线程的调度优先级ThreadState获取一个值,该值包含当前线程的状态6.3线程开发基础知识4.ThreadState属性:属性值说明Aborted线程已停止AbortRequested线程的Thread.Abort()方法已被调用,但是线程还未停止Background线程在后台执行,与属性Thread.IsBackground有关;不妨碍程序的终止Running线程正在正常运行Stopped线程已被停止StopRequested线程正在被要求停止Suspended线程已被挂起(此状态下,可以通过调用Resume()方法重新运行)SuspendRequested线程正在要求被挂起,但是未来得及响应Unstarted未调用Thread.Start()开始线程的运行WaitSleepJoin线程因调用了Wait()、Sleep()或Join()等方法处于封锁状态6.3线程开发基础知识5.线程优先级在C#中,一个线程的优先级由高到低可分为5种:Highest、AboveNormal、Normal、BelowNormal和Lowest。对于新创建但未指定优先级的线程,系统默认设置其优先级为Normal。示例代码如下://将线程的优先级设置为最高优先
本文标题:第6章 进程与线程开发程序设计
链接地址:https://www.777doc.com/doc-3972130 .html