第13章C#高級(jí)特性_第1頁(yè)
第13章C#高級(jí)特性_第2頁(yè)
第13章C#高級(jí)特性_第3頁(yè)
第13章C#高級(jí)特性_第4頁(yè)
第13章C#高級(jí)特性_第5頁(yè)
已閱讀5頁(yè),還剩73頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、第第13章章C#高級(jí)特性高級(jí)特性13.1 泛泛 型型13.2 反反 射射13.3 多線程程序設(shè)計(jì)多線程程序設(shè)計(jì) 13.1 泛泛 型型13.1.1 什么是泛型什么是泛型所謂泛型,是指通過(guò)參數(shù)化類型來(lái)實(shí)現(xiàn)在同一份代碼所謂泛型,是指通過(guò)參數(shù)化類型來(lái)實(shí)現(xiàn)在同一份代碼上操作多種數(shù)據(jù)類型,泛型編程是一種編程范式,它利用上操作多種數(shù)據(jù)類型,泛型編程是一種編程范式,它利用“參數(shù)化類型參數(shù)化類型”將類型抽象化,從而實(shí)現(xiàn)更為靈活的復(fù)用。將類型抽象化,從而實(shí)現(xiàn)更為靈活的復(fù)用。泛型類型和普通類型的區(qū)別在于泛型類型與一組類型參數(shù)泛型類型和普通類型的區(qū)別在于泛型類型與一組類型參數(shù)或類型變量關(guān)聯(lián)?;蝾愋妥兞筷P(guān)聯(lián)。C#泛型能

2、力是由泛型能力是由CLR在運(yùn)行時(shí)支持,區(qū)別于在運(yùn)行時(shí)支持,區(qū)別于C+的編的編譯時(shí)模板機(jī)制和譯時(shí)模板機(jī)制和Java的編譯時(shí)的的編譯時(shí)的“搽拭法搽拭法”。這使得泛型。這使得泛型能力可以在各個(gè)支持能力可以在各個(gè)支持CLR的語(yǔ)言之間進(jìn)行無(wú)縫的互操作。的語(yǔ)言之間進(jìn)行無(wú)縫的互操作。數(shù)據(jù)的抽象:數(shù)據(jù)的抽象:int MAX(int a,int b) return ab?a:b; double MAX1(double a,double b) return ab?a:b; int MAX(int a,int b) return ab?a:b; double MAX(double a,double b) retur

3、n ab?a:b; 重載重載數(shù)據(jù)類型的抽象:數(shù)據(jù)類型的抽象: T MAX(T a,T b) return ab?a:b; 泛型泛型13.1.2 泛型的聲明和使用泛型的聲明和使用通常先聲明泛型,然后通過(guò)類型實(shí)例化來(lái)使用泛型。通常先聲明泛型,然后通過(guò)類型實(shí)例化來(lái)使用泛型。定義泛型的語(yǔ)法格式如下:定義泛型的語(yǔ)法格式如下:訪問(wèn)修飾符訪問(wèn)修飾符返回類型返回類型 泛型名稱泛型名稱其中,其中,“泛型名稱泛型名稱”要符合標(biāo)識(shí)符的定義。尖括號(hào)要符合標(biāo)識(shí)符的定義。尖括號(hào)表示類型參數(shù)列表,可以包含一個(gè)或多個(gè)類型參數(shù),如表示類型參數(shù)列表,可以包含一個(gè)或多個(gè)類型參數(shù),如。C#中常用的泛型有泛型類和泛型方法,例如:中常用

4、的泛型有泛型類和泛型方法,例如:class Stack/聲明泛型類聲明泛型類 T dataMaxSize;int top;void swap(ref T a,ref T b)/定義泛型方法定義泛型方法 T tmp = a;a = b;b = tmp;【例【例13.0】 分析以下程序執(zhí)行結(jié)果。分析以下程序執(zhí)行結(jié)果。 public class abc public A a; public B b; public void show() MessageBox.Show(a.ToString() + ,+b.ToString(); private void button2_Click(object s

5、ender, EventArgs e) abc a = new abc(); a.a = 2; a.b = 3.8; a.show(); 【例【例13.1】 分析以下程序的執(zhí)行結(jié)果。分析以下程序的執(zhí)行結(jié)果。using System;namespace Proj13_1class Stack/聲明棧泛型類聲明棧泛型類int maxsize;/棧中元素最多個(gè)數(shù)棧中元素最多個(gè)數(shù)T data;/存放棧中存放棧中T類型的元素類型的元素int top;/棧頂指針棧頂指針public Stack()/構(gòu)造函數(shù)構(gòu)造函數(shù)maxsize = 10;data = new Tmaxsize;top = -1;publ

6、ic Stack(int n)/重載構(gòu)造函數(shù)重載構(gòu)造函數(shù)maxsize = n;data = new Tmaxsize;top = -1;public bool StackEmpty()/判斷??辗椒ㄅ袛鄺?辗椒?return top = -1; public bool Push(T e)/元素元素e進(jìn)棧方法進(jìn)棧方法 if (top = maxsize - 1)/棧滿返回棧滿返回false return false; top+; datatop = e; return true; public bool Pop(ref T e) /元素出棧方法元素出棧方法 if (top = -1)/??辗祷?/p>

7、??辗祷豧alse return false; e = datatop; top-; return true; class Program static void Main(string args) int e = 0; Stack s = new Stack();/定義整數(shù)棧定義整數(shù)棧 s.Push(1);/進(jìn)棧進(jìn)棧3個(gè)整數(shù)個(gè)整數(shù) s.Push(3); s.Push(2); Console.Write(整數(shù)棧出棧次序:整數(shù)棧出棧次序:); while (!s.StackEmpty()/棧不空時(shí)出棧元素棧不空時(shí)出棧元素 s.Pop(ref e); Console.Write(0 , e); C

8、onsole.WriteLine(); string e1 = ;Stack s1 = new Stack(); /定義字符串棧定義字符串棧s1.Push(Mary);/進(jìn)棧進(jìn)棧3個(gè)字符串個(gè)字符串s1.Push(John);s1.Push(Simth);Console.Write(字符串棧出棧次序:字符串棧出棧次序:);while (!s1.StackEmpty()/棧不空時(shí)出棧元素棧不空時(shí)出棧元素 s1.Pop(ref e1); Console.Write(0 , e1);Console.WriteLine(); 本程序先聲明了一個(gè)泛型棧本程序先聲明了一個(gè)泛型棧Stack,然后實(shí)例化為,然后

9、實(shí)例化為整數(shù)棧整數(shù)棧s和字符串棧和字符串棧s1,各自進(jìn)棧,各自進(jìn)棧3個(gè)元素后并出棧,程序個(gè)元素后并出棧,程序執(zhí)行結(jié)果如圖執(zhí)行結(jié)果如圖13.1所示。所示。13.2 反反 射射13.2.1 反射概述反射概述反射是一種機(jī)制,通過(guò)這種機(jī)制可以知道一個(gè)未知類反射是一種機(jī)制,通過(guò)這種機(jī)制可以知道一個(gè)未知類型的類型信息。型的類型信息。例如有一個(gè)對(duì)象,它不是我們定義的,既可能是通過(guò)例如有一個(gè)對(duì)象,它不是我們定義的,既可能是通過(guò)網(wǎng)絡(luò)捕捉到的,也可能是使用泛型定義的,但我們想知道網(wǎng)絡(luò)捕捉到的,也可能是使用泛型定義的,但我們想知道這個(gè)對(duì)象的類型信息,想知道這個(gè)對(duì)象有哪些方法或者屬這個(gè)對(duì)象的類型信息,想知道這個(gè)對(duì)象有

10、哪些方法或者屬性什么的,甚至想進(jìn)一步調(diào)用這個(gè)對(duì)象的方法。關(guān)鍵是現(xiàn)性什么的,甚至想進(jìn)一步調(diào)用這個(gè)對(duì)象的方法。關(guān)鍵是現(xiàn)在只知道它是一個(gè)對(duì)象,不知道它的類型,自然不會(huì)知道在只知道它是一個(gè)對(duì)象,不知道它的類型,自然不會(huì)知道它有哪些方法等信息,這時(shí)該怎么辦呢?它有哪些方法等信息,這時(shí)該怎么辦呢?反射機(jī)制就是解決這么一個(gè)問(wèn)題的,通過(guò)反射機(jī)制就反射機(jī)制就是解決這么一個(gè)問(wèn)題的,通過(guò)反射機(jī)制就可以知道未知類型對(duì)象的類型信息??梢灾牢粗愋蛯?duì)象的類型信息。反射提供了封裝程序集、模塊和類型的對(duì)象(反射提供了封裝程序集、模塊和類型的對(duì)象(Type類類型),可以使用反射動(dòng)態(tài)創(chuàng)建類型的實(shí)例,將類型綁定到型),可以使用反

11、射動(dòng)態(tài)創(chuàng)建類型的實(shí)例,將類型綁定到現(xiàn)有對(duì)象,或從現(xiàn)有對(duì)象獲取類型并調(diào)用其方法或訪問(wèn)其現(xiàn)有對(duì)象,或從現(xiàn)有對(duì)象獲取類型并調(diào)用其方法或訪問(wèn)其字段和屬性。如果代碼中使用了屬性,可以利用反射對(duì)它字段和屬性。如果代碼中使用了屬性,可以利用反射對(duì)它們進(jìn)行訪問(wèn)。們進(jìn)行訪問(wèn)。歸納起來(lái),反射在下列情況下很有用:歸納起來(lái),反射在下列情況下很有用:l 需要訪問(wèn)程序元數(shù)據(jù)的屬性。需要訪問(wèn)程序元數(shù)據(jù)的屬性。l 檢查和實(shí)例化程序集中的類型。檢查和實(shí)例化程序集中的類型。l 在運(yùn)行時(shí)構(gòu)建新類型。在運(yùn)行時(shí)構(gòu)建新類型。l 執(zhí)行后期綁定,訪問(wèn)在運(yùn)行時(shí)創(chuàng)建的類型的方法。執(zhí)行后期綁定,訪問(wèn)在運(yùn)行時(shí)創(chuàng)建的類型的方法。13.2.2 反射中常

12、用的類反射中常用的類1. Type類類System.Reflection是反射的命名空間,而是反射的命名空間,而Type類為類為System.Reflection功能的根,也是訪問(wèn)元數(shù)據(jù)的主要方式。功能的根,也是訪問(wèn)元數(shù)據(jù)的主要方式。Type類表示類型聲明,包括類類型、接口類型、數(shù)組類表示類型聲明,包括類類型、接口類型、數(shù)組類型、值類型、枚舉類型、類型參數(shù)、泛型類型定義,以類型、值類型、枚舉類型、類型參數(shù)、泛型類型定義,以及開(kāi)放或封閉構(gòu)造的泛型類型。及開(kāi)放或封閉構(gòu)造的泛型類型。公共屬性公共屬性說(shuō)明說(shuō)明IsAbstract獲取一個(gè)值,通過(guò)該值指示獲取一個(gè)值,通過(guò)該值指示Type是否為抽象的并且必

13、須被重是否為抽象的并且必須被重寫(xiě)寫(xiě)IsArray獲取一個(gè)值,通過(guò)該值指示獲取一個(gè)值,通過(guò)該值指示Type是否為數(shù)組是否為數(shù)組IsByRef獲取一個(gè)值,通過(guò)該值指示獲取一個(gè)值,通過(guò)該值指示Type是否由引用傳遞是否由引用傳遞IsClass獲取一個(gè)值,通過(guò)該值指示獲取一個(gè)值,通過(guò)該值指示Type是否是一個(gè)類,即不是值類是否是一個(gè)類,即不是值類型或接口型或接口IsInterface獲取一個(gè)值,通過(guò)該值指示獲取一個(gè)值,通過(guò)該值指示Type是否為接口,即不是類或值是否為接口,即不是類或值類型類型IsSubclassOf確定當(dāng)前確定當(dāng)前Type表示的類是否是從指定的表示的類是否是從指定的Type表示的類派

14、生的表示的類派生的MakeArrayType返回一個(gè)表示當(dāng)前類型的一維數(shù)組(下限為零)的返回一個(gè)表示當(dāng)前類型的一維數(shù)組(下限為零)的Type對(duì)象對(duì)象Module獲取在其中定義當(dāng)前獲取在其中定義當(dāng)前Type的模塊的模塊Name獲取當(dāng)前成員的名稱獲取當(dāng)前成員的名稱Namespace獲取獲取Type的命名空間的命名空間ReflectedType獲取用于獲取該成員的類對(duì)象獲取用于獲取該成員的類對(duì)象Type類的屬性類的屬性方法方法說(shuō)明說(shuō)明GetElementType當(dāng)在派生類中重寫(xiě)時(shí),返回當(dāng)前數(shù)組、指針或引用類型包含的當(dāng)在派生類中重寫(xiě)時(shí),返回當(dāng)前數(shù)組、指針或引用類型包含的或引用的對(duì)象的或引用的對(duì)象的Ty

15、peGetEvent獲取由當(dāng)前獲取由當(dāng)前Type聲明或繼承的特定事件聲明或繼承的特定事件GetEvents獲取由當(dāng)前獲取由當(dāng)前Type聲明或繼承的事件聲明或繼承的事件GetField獲取當(dāng)前獲取當(dāng)前Type的特定字段的特定字段GetFields獲取當(dāng)前獲取當(dāng)前Type的字段的字段GetInterface獲取由當(dāng)前獲取由當(dāng)前Type實(shí)現(xiàn)或繼承的特定接口實(shí)現(xiàn)或繼承的特定接口GetInterfaces當(dāng)在派生類中重寫(xiě)時(shí),獲取由當(dāng)前當(dāng)在派生類中重寫(xiě)時(shí),獲取由當(dāng)前Type實(shí)現(xiàn)或繼承的所有接口實(shí)現(xiàn)或繼承的所有接口GetMember獲取當(dāng)前獲取當(dāng)前Type的指定成員的指定成員GetMembers獲取當(dāng)前獲取

16、當(dāng)前Type的成員(包括屬性、方法、字段、事件等)的成員(包括屬性、方法、字段、事件等)GetMethod獲取當(dāng)前獲取當(dāng)前Type的特定方法的特定方法GetMethods獲取當(dāng)前獲取當(dāng)前Type的方法的方法GetProperties獲取當(dāng)前獲取當(dāng)前Type的屬性的屬性GetProperty獲取當(dāng)前獲取當(dāng)前Type的特定屬性的特定屬性InvokeMember使用指定的綁定約束并匹配指定的參數(shù)列表,調(diào)用指定成員使用指定的綁定約束并匹配指定的參數(shù)列表,調(diào)用指定成員Type類的方法類的方法歸納起來(lái),得到一個(gè)歸納起來(lái),得到一個(gè)Type實(shí)例的三種方法如下:實(shí)例的三種方法如下:(1)使用)使用System.

17、Object.GetType(),例如:,例如:Person pe=new Person();/定義定義pe為為person類的一個(gè)對(duì)象類的一個(gè)對(duì)象Type t=pe.GetType();這樣這樣t為為pe的的Type對(duì)象。對(duì)象。(2)使用)使用System.Type.GetType()靜態(tài)方法,參數(shù)為靜態(tài)方法,參數(shù)為類型的完全限定名。例如:類型的完全限定名。例如:Type t=Type.GetType(MyNs.Person);其中,其中,MyNs.Person為為MyNs命名空間中的命名空間中的Person類,類,這樣這樣t為該類的為該類的Type對(duì)象。對(duì)象。(3)使用)使用typeof運(yùn)

18、算符,例如:運(yùn)算符,例如:Type t=typeof(Person);其中其中Person為一個(gè)類,這樣為一個(gè)類,這樣t為該類的為該類的Type對(duì)象。對(duì)象。2. System.Reflection反射命名空間反射命名空間System.Reflection反射命名空間包含提供加載類型、反射命名空間包含提供加載類型、方法和字段的有組織的視圖的類和接口,具有動(dòng)態(tài)創(chuàng)建方法和字段的有組織的視圖的類和接口,具有動(dòng)態(tài)創(chuàng)建和調(diào)用類型的功能。其中主要的類及其功能如下:和調(diào)用類型的功能。其中主要的類及其功能如下:l Assembly類類:通過(guò)它可以加載、了解和操作一個(gè)程:通過(guò)它可以加載、了解和操作一個(gè)程序集。序集

19、。l AssemblyName類類:通過(guò)它可以找到大量隱藏在程:通過(guò)它可以找到大量隱藏在程序集的身份中的信息,如版本信息、區(qū)域信息等。序集的身份中的信息,如版本信息、區(qū)域信息等。l ConstructorInfo類類:用于發(fā)現(xiàn)構(gòu)造函數(shù)及調(diào)用構(gòu)造:用于發(fā)現(xiàn)構(gòu)造函數(shù)及調(diào)用構(gòu)造函數(shù)。通過(guò)對(duì)函數(shù)。通過(guò)對(duì)ConstructorInfo調(diào)用調(diào)用Invoke來(lái)創(chuàng)建對(duì)來(lái)創(chuàng)建對(duì)象,其中象,其中ConstructorInfo是由是由Type對(duì)象的對(duì)象的GetConstructors或或GetConstructor方法返回的。方法返回的。l EventInfo類類:通過(guò)它可以找到事件的信息。:通過(guò)它可以找到事件的信

20、息。l FieldInfo類類:通過(guò)它可以找到字段的信息。:通過(guò)它可以找到字段的信息。l MethodInfo類類:通過(guò)它可以找到方法的信息。:通過(guò)它可以找到方法的信息。l ParameterInfo類類:通過(guò)它可以找到參數(shù)的信息。:通過(guò)它可以找到參數(shù)的信息。l PropertyInfo類類:通過(guò)它可以找到屬性的信息。:通過(guò)它可以找到屬性的信息。l MemberInfo類類:它是一個(gè)抽象基類,為:它是一個(gè)抽象基類,為EventInfo、FieldInfo、MethodInfo、PropertyInfo等類型定義了等類型定義了公共的行為。公共的行為。l Module類類:用來(lái)訪問(wèn)帶有多文件程序集

21、的給定模塊。:用來(lái)訪問(wèn)帶有多文件程序集的給定模塊。l DefaultMemberAttribute類類:定義某類型的成員,該:定義某類型的成員,該成員是成員是InvokeMember使用的默認(rèn)成員。使用的默認(rèn)成員。 公共屬性公共屬性說(shuō)明說(shuō)明EntryPoint獲取此程序集的入口點(diǎn)獲取此程序集的入口點(diǎn)FullName獲取程序集的顯示名稱獲取程序集的顯示名稱Location獲取包含清單的已加載文件的路徑或位置獲取包含清單的已加載文件的路徑或位置ManifestModule獲取包含當(dāng)前程序集清單的模塊獲取包含當(dāng)前程序集清單的模塊其中重要的其中重要的Assembly類,它的常用屬性和常用方法類,它的常

22、用屬性和常用方法如下。如下。Assembly類的常用屬性類的常用屬性 方法方法說(shuō)明說(shuō)明GetFiles獲取程序集清單文件表中的文件獲取程序集清單文件表中的文件GetModule獲取此程序集中的指定模塊獲取此程序集中的指定模塊GetModules獲取作為此程序集的一部分的所有模塊獲取作為此程序集的一部分的所有模塊GetType獲取表示指定類型的獲取表示指定類型的Type對(duì)象對(duì)象GetTypes獲取此程序集中定義的類型獲取此程序集中定義的類型LoadFile加載程序集文件的內(nèi)容加載程序集文件的內(nèi)容LoadFrom在已知程序集的文件名或路徑等信息時(shí)加載程序集在已知程序集的文件名或路徑等信息時(shí)加載程序

23、集LoadModule加載此程序集的內(nèi)部模塊加載此程序集的內(nèi)部模塊Assembly類的常用方法類的常用方法 13.2.3 反射的應(yīng)用示例反射的應(yīng)用示例1. 通過(guò)反射查看類型的成員信息通過(guò)反射查看類型的成員信息查看類型信息的過(guò)程如下:查看類型信息的過(guò)程如下:(1)獲取指定類型的一個(gè))獲取指定類型的一個(gè)Type對(duì)象或?qū)ο蠡騎ype對(duì)象數(shù)組。對(duì)象數(shù)組。(2)通過(guò))通過(guò)Type類的許多方法來(lái)發(fā)現(xiàn)與該類型的成員有類的許多方法來(lái)發(fā)現(xiàn)與該類型的成員有關(guān)的信息。關(guān)的信息。【例【例13.2】 編寫(xiě)一個(gè)程序,通過(guò)反射輸出編寫(xiě)一個(gè)程序,通過(guò)反射輸出System.Object類的方法、字段和構(gòu)造函數(shù)的信息。類的方法、

24、字段和構(gòu)造函數(shù)的信息。解解:先通過(guò):先通過(guò)Type的的GetTypes()方法獲取方法獲取System.Object類類的的Type對(duì)象對(duì)象t,然后用,然后用Type類的類的GetMethods()、GetFields()、GetConstructors()分別獲取分別獲取t對(duì)象的方法、字段和構(gòu)造函數(shù)信對(duì)象的方法、字段和構(gòu)造函數(shù)信息并輸出。程序如下:息并輸出。程序如下:using System;using System.Reflection;namespace Proj8_2class Programstatic void Main(string args) string classname

25、= System.Object;Console.WriteLine(0類類,classname);Type t = Type.GetType(classname);MethodInfo m = t.GetMethods();Console.WriteLine( 0的方法個(gè)數(shù)的方法個(gè)數(shù):1, t.FullName, m.Length);foreach(MethodInfo item in m) Console.WriteLine(t0 ,item.Name); FieldInfo f = t.GetFields(); Console.WriteLine( 0的字段個(gè)數(shù)的字段個(gè)數(shù):1, t.Ful

26、lName, f.Length); foreach (FieldInfo item in f) Console.WriteLine(t0 , item.Name); ConstructorInfo c = t.GetConstructors();Console.WriteLine( 0的構(gòu)造函數(shù)個(gè)數(shù)的構(gòu)造函數(shù)個(gè)數(shù):1, t.FullName, c.Length);foreach (ConstructorInfo item in c)Console.WriteLine(t0 , item.Name); 程序執(zhí)行結(jié)果程序執(zhí)行結(jié)果2. 通過(guò)反射調(diào)用未知類的某方法通過(guò)反射調(diào)用未知類的某方法調(diào)用未知類的

27、某方法的過(guò)程如下:調(diào)用未知類的某方法的過(guò)程如下:(1)假設(shè)一個(gè)未知類)假設(shè)一個(gè)未知類c屬于某個(gè)屬于某個(gè)DLL文件文件xyz.dll,采,采用用Assembly.LoadFrom(xyz.dll)加載該程序集。加載該程序集。(2)調(diào)用)調(diào)用assembly.GetTypes()方法得到一個(gè)方法得到一個(gè)Type對(duì)對(duì)象數(shù)組象數(shù)組t。(3)通過(guò))通過(guò)Type.GetConstructor()方法得到某個(gè)對(duì)象方法得到某個(gè)對(duì)象的構(gòu)造函數(shù)。的構(gòu)造函數(shù)。(4)通過(guò))通過(guò)ConstructorInfo.Invoke()方法調(diào)用構(gòu)造函方法調(diào)用構(gòu)造函數(shù)創(chuàng)建未知類的對(duì)象數(shù)創(chuàng)建未知類的對(duì)象s。(5)通過(guò)對(duì)象)通過(guò)對(duì)象s

28、調(diào)用某方法。調(diào)用某方法。【例【例13.3】 有一個(gè)項(xiàng)目有一個(gè)項(xiàng)目Proj8_3,通過(guò)添加代碼文件模,通過(guò)添加代碼文件模板向其中添加一個(gè)板向其中添加一個(gè)Sport.cs文件,該文件的內(nèi)容如下:文件,該文件的內(nèi)容如下:using System;public abstract class Sport/體育運(yùn)動(dòng)類體育運(yùn)動(dòng)類protected string name; /項(xiàng)目名項(xiàng)目名public abstract string GetDuration();/獲取比賽時(shí)間獲取比賽時(shí)間public abstract string GetName();/獲取項(xiàng)目名獲取項(xiàng)目名在命令行方式下使用以下命令生成在命令

29、行方式下使用以下命令生成Sport.dll文件:文件:csc/target:library Sport.cs命令行編譯命令命令行編譯命令 采用命令行方式對(duì)采用命令行方式對(duì)C#文件進(jìn)行編譯的程序是文件進(jìn)行編譯的程序是csc.exe,它通常位于系統(tǒng)目,它通常位于系統(tǒng)目錄下的錄下的Microsoft.NETFramework文件夾中,根據(jù)每臺(tái)計(jì)算機(jī)上的文件夾中,根據(jù)每臺(tái)計(jì)算機(jī)上的確 切 配 置 , 此 位 置 可 能 有 所 不 同 。 一 般 情 況 下 其 位 置 是確 切 配 置 , 此 位 置 可 能 有 所 不 同 。 一 般 情 況 下 其 位 置 是C:WindowsMicrosoft

30、.NETFrameworkv2.0.50727文件夾中。文件夾中。 為了進(jìn)行命令行編譯,在為了進(jìn)行命令行編譯,在Windows下運(yùn)行下運(yùn)行cmd命令,進(jìn)入存放項(xiàng)目的文命令,進(jìn)入存放項(xiàng)目的文件夾,如件夾,如H:C#2005ch8Proj8_3Proj8_3,其中包含有本項(xiàng)目的,其中包含有本項(xiàng)目的C#文件。為文件。為了能夠執(zhí)行了能夠執(zhí)行csc程序,通過(guò)程序,通過(guò)path設(shè)置路徑,即在命令行方式中輸入以下命令:設(shè)置路徑,即在命令行方式中輸入以下命令:path C:WindowsMicrosoft.NETFrameworkv2.0.50727 常用的編譯命令如下:常用的編譯命令如下: (1)csc/t

31、arget:library 模塊名模塊名 該命令使編譯器創(chuàng)建一個(gè)動(dòng)態(tài)鏈接庫(kù)(該命令使編譯器創(chuàng)建一個(gè)動(dòng)態(tài)鏈接庫(kù)(DLL)而不是一個(gè)可執(zhí)行文件)而不是一個(gè)可執(zhí)行文件(EXE)。)。 (2)csc/reference:filename 該命令導(dǎo)致編譯器將指定文件中的該命令導(dǎo)致編譯器將指定文件中的public類型信息導(dǎo)入到當(dāng)前項(xiàng)目中,從類型信息導(dǎo)入到當(dāng)前項(xiàng)目中,從而可以從指定的程序集文件引用元數(shù)據(jù)。而可以從指定的程序集文件引用元數(shù)據(jù)。filename包含程序集清單的文件的包含程序集清單的文件的名稱。若要導(dǎo)入多個(gè)文件,請(qǐng)為每個(gè)文件包括一個(gè)單獨(dú)的名稱。若要導(dǎo)入多個(gè)文件,請(qǐng)為每個(gè)文件包括一個(gè)單獨(dú)的/refe

32、rence選項(xiàng)。選項(xiàng)。同樣通過(guò)添加代碼文件模板向其中添加一個(gè)同樣通過(guò)添加代碼文件模板向其中添加一個(gè)SomeSports.cs文件,該文件的內(nèi)容如下:文件,該文件的內(nèi)容如下:using System;public class Basketball : Sportpublic Basketball()/籃球類籃球類name = 籃球籃球; public override string GetDuration()return 共節(jié),每節(jié)分鐘共節(jié),每節(jié)分鐘; public override string GetName()return name; public class Hockey : Sport

33、/曲棍球類曲棍球類public Hockey()name = 曲棍球曲棍球; public override string GetDuration()return 兩個(gè)半場(chǎng),各分鐘兩個(gè)半場(chǎng),各分鐘; public override string GetName()return name; public class Football : Sport/足球類足球類public Football()name = 足球足球; public override string GetDuration()return 兩個(gè)半場(chǎng),各分鐘兩個(gè)半場(chǎng),各分鐘; public override string GetNa

34、me()return name; 在命令行方式下使用以下命令生成在命令行方式下使用以下命令生成SomeSports.dll文件:文件:csc/target:library /reference:Sport.dll SomeSports.cs這樣就生成兩個(gè)動(dòng)態(tài)鏈接庫(kù)文件這樣就生成兩個(gè)動(dòng)態(tài)鏈接庫(kù)文件Sport.dll和和SomeSports.dll?,F(xiàn)要在現(xiàn)要在Program類類Main中設(shè)計(jì)相應(yīng)代碼,根據(jù)用戶選擇的體育中設(shè)計(jì)相應(yīng)代碼,根據(jù)用戶選擇的體育項(xiàng)目輸出相應(yīng)的比賽時(shí)間。項(xiàng)目輸出相應(yīng)的比賽時(shí)間。解:解:由于在設(shè)計(jì)由于在設(shè)計(jì)Program.cs程序時(shí),提供的程序時(shí),提供的Sport.dll和和

35、SomeSports.dll都是動(dòng)態(tài)鏈接庫(kù),不知道其中每個(gè)類是如何都是動(dòng)態(tài)鏈接庫(kù),不知道其中每個(gè)類是如何聲明的,只知道聲明的,只知道GetName()和和GetDuration()兩個(gè)方法的功能,兩個(gè)方法的功能,為此采用反射技術(shù)。設(shè)計(jì)為此采用反射技術(shù)。設(shè)計(jì)Program.cs程序如下:程序如下:using System;using System.Reflection;namespace Proj8_3 class Programstatic void Main(string args)int i, j; if (args.GetLength(0) 1) /命令行輸入的參數(shù)不正確命令行輸入的參數(shù)

36、不正確Console.WriteLine(用法用法:Program dll庫(kù)名庫(kù)名); else Assembly assembly=Assembly.LoadFrom(args0); /獲取程序集對(duì)象獲取程序集對(duì)象 Type types = assembly.GetTypes(); Console.WriteLine(assembly.GetName().Name + 包含的項(xiàng)目名如下包含的項(xiàng)目名如下:);for (i = 0; i types.GetLength(0); +i)Console.WriteLine(r + i + : + typesi.Name);i = types.Leng

37、th - 1; Console.Write(請(qǐng)選擇請(qǐng)選擇(0- + i + ):); j = Convert.ToInt32(Console.ReadLine(); Console.WriteLine(); if (typesj.IsSubclassOf(typeof(Sport) /若若typesj是是Sport的子類的子類 ConstructorInfo ci = typesj.GetConstructor(new Type0); Sport sport = (Sport)ci.Invoke(new Object0); /創(chuàng)建創(chuàng)建sport對(duì)象對(duì)象 Console.WriteLine(sp

38、ort.GetName()+比賽時(shí)間比賽時(shí)間:+ sport.GetDuration(); else Console.WriteLine(typesj.Name + 不屬于指定的體育項(xiàng)目不屬于指定的體育項(xiàng)目); 在命令行中輸入以下命令在命令行中輸入以下命令Program.exe文件:文件:csc/reference:Sport.dll Program.cs在命令行中輸入以下命令執(zhí)行在命令行中輸入以下命令執(zhí)行Program.exe:Program SomeSports.dll程序的一次執(zhí)行結(jié)果如圖程序的一次執(zhí)行結(jié)果如圖13.3所示,在出現(xiàn)各種提示所示,在出現(xiàn)各種提示后輸入后輸入2,輸出足球的比賽

39、時(shí)間。,輸出足球的比賽時(shí)間。.dll只需知道類和方法,可只需知道類和方法,可以通過(guò)反射技術(shù)使用它。以通過(guò)反射技術(shù)使用它。以前我們必須知道一個(gè)類的完整定義,才可以使用以前我們必須知道一個(gè)類的完整定義,才可以使用這個(gè)類。這個(gè)類。采用反射技術(shù):采用反射技術(shù):13.3 多線程程序設(shè)計(jì)多線程程序設(shè)計(jì)13.3.1 多線程的概述多線程的概述當(dāng)一個(gè)程序開(kāi)始運(yùn)行時(shí),它就是一個(gè)進(jìn)程。當(dāng)一個(gè)程序開(kāi)始運(yùn)行時(shí),它就是一個(gè)進(jìn)程。進(jìn)程所指包括執(zhí)行中的程序和程序所使用到的內(nèi)存和進(jìn)程所指包括執(zhí)行中的程序和程序所使用到的內(nèi)存和系統(tǒng)資源。系統(tǒng)資源。而一個(gè)進(jìn)程又是由多個(gè)線程所組成的,線程是程序中而一個(gè)進(jìn)程又是由多個(gè)線程所組成的,線程

40、是程序中的一個(gè)執(zhí)行流,每個(gè)線程都有自己的專有寄存器(棧指針、的一個(gè)執(zhí)行流,每個(gè)線程都有自己的專有寄存器(棧指針、程序計(jì)數(shù)器等),但代碼區(qū)是共享的,即不同的線程可以程序計(jì)數(shù)器等),但代碼區(qū)是共享的,即不同的線程可以執(zhí)行同樣的函數(shù)。多線程是指程序中包含多個(gè)執(zhí)行流,即執(zhí)行同樣的函數(shù)。多線程是指程序中包含多個(gè)執(zhí)行流,即在一個(gè)程序中可以同時(shí)運(yùn)行多個(gè)不同的線程來(lái)執(zhí)行不同的在一個(gè)程序中可以同時(shí)運(yùn)行多個(gè)不同的線程來(lái)執(zhí)行不同的任務(wù),也就是說(shuō)允許單個(gè)程序創(chuàng)建多個(gè)并行執(zhí)行的線程來(lái)任務(wù),也就是說(shuō)允許單個(gè)程序創(chuàng)建多個(gè)并行執(zhí)行的線程來(lái)完成各自的任務(wù)。完成各自的任務(wù)。 從上圖可以看出,幾乎所有的進(jìn)程都擁有兩個(gè)以上的線程。從

41、而從上圖可以看出,幾乎所有的進(jìn)程都擁有兩個(gè)以上的線程。從而可以看出,線程是提供應(yīng)用程序性能的重要手段之一,尤其在多核可以看出,線程是提供應(yīng)用程序性能的重要手段之一,尤其在多核CPU的機(jī)器上尤為明顯。的機(jī)器上尤為明顯。 一個(gè)一個(gè)C#程序開(kāi)始于一個(gè)單線程,這個(gè)單線程是被程序開(kāi)始于一個(gè)單線程,這個(gè)單線程是被CLR和操作系統(tǒng)(也稱為和操作系統(tǒng)(也稱為“主線程主線程”)自動(dòng)創(chuàng)建的,并具有多)自動(dòng)創(chuàng)建的,并具有多線程創(chuàng)建額外的線程。線程創(chuàng)建額外的線程。 在在C#應(yīng)用程序中,第一個(gè)線程總是應(yīng)用程序中,第一個(gè)線程總是Main()方法,因?yàn)榉椒?,因?yàn)榈谝粋€(gè)線程是由第一個(gè)線程是由.NET運(yùn)行庫(kù)開(kāi)始執(zhí)行的,運(yùn)行庫(kù)開(kāi)

42、始執(zhí)行的,Main()方法方法是是.NET運(yùn)行庫(kù)選擇的第一個(gè)方法。后續(xù)的線程由應(yīng)用程序運(yùn)行庫(kù)選擇的第一個(gè)方法。后續(xù)的線程由應(yīng)用程序在內(nèi)部啟動(dòng),即應(yīng)用程序可以創(chuàng)建和啟動(dòng)新的線程。在內(nèi)部啟動(dòng),即應(yīng)用程序可以創(chuàng)建和啟動(dòng)新的線程。多線程:多線程:在同一時(shí)間執(zhí)行多個(gè)任務(wù)的功能,稱為多線在同一時(shí)間執(zhí)行多個(gè)任務(wù)的功能,稱為多線程或自由線程。程或自由線程。多線程的優(yōu)點(diǎn):多線程的優(yōu)點(diǎn):可以同時(shí)完成多個(gè)任務(wù);可以使程序可以同時(shí)完成多個(gè)任務(wù);可以使程序的響應(yīng)速度更快;可以讓占用大量處理時(shí)間的任務(wù)或當(dāng)前的響應(yīng)速度更快;可以讓占用大量處理時(shí)間的任務(wù)或當(dāng)前沒(méi)有進(jìn)行處理的任務(wù)定期將處理時(shí)間讓給別的任務(wù);可以沒(méi)有進(jìn)行處理的任

43、務(wù)定期將處理時(shí)間讓給別的任務(wù);可以隨時(shí)停止任務(wù);可以設(shè)置每個(gè)任務(wù)的優(yōu)先級(jí)以優(yōu)化程序性隨時(shí)停止任務(wù);可以設(shè)置每個(gè)任務(wù)的優(yōu)先級(jí)以優(yōu)化程序性能。能。多線程的缺點(diǎn):多線程的缺點(diǎn):對(duì)資源的共享訪問(wèn)可能造成沖突(對(duì)對(duì)資源的共享訪問(wèn)可能造成沖突(對(duì)共享資源的訪問(wèn)進(jìn)行同步或控制)共享資源的訪問(wèn)進(jìn)行同步或控制) ;程序的整體運(yùn)行速度;程序的整體運(yùn)行速度減慢等等。減慢等等。13.3.2 線程命名空間線程命名空間線程命名空間是線程命名空間是System.Threading,它提供了多線程,它提供了多線程程序設(shè)計(jì)的類和接口等,用以執(zhí)行諸如創(chuàng)建和啟動(dòng)線程、程序設(shè)計(jì)的類和接口等,用以執(zhí)行諸如創(chuàng)建和啟動(dòng)線程、同步多個(gè)線程、

44、掛起線程和中止線程等任務(wù)。其中有關(guān)線同步多個(gè)線程、掛起線程和中止線程等任務(wù)。其中有關(guān)線程方面的類如下:程方面的類如下:l Thread類:用于創(chuàng)建并控制線程、設(shè)置其優(yōu)先級(jí)并獲取其狀類:用于創(chuàng)建并控制線程、設(shè)置其優(yōu)先級(jí)并獲取其狀態(tài)。態(tài)。l Monitor類:提供同步對(duì)對(duì)象的訪問(wèn)的機(jī)制。類:提供同步對(duì)對(duì)象的訪問(wèn)的機(jī)制。l Mutex類:一個(gè)同步基元,也可用于進(jìn)程間同步。類:一個(gè)同步基元,也可用于進(jìn)程間同步。l ThreadAbortException類:在對(duì)類:在對(duì)Abort方法進(jìn)行調(diào)用時(shí)引發(fā)方法進(jìn)行調(diào)用時(shí)引發(fā)的異常。無(wú)法繼承此類。的異常。無(wú)法繼承此類。l ThreadInterruptedExc

45、eption類:中斷處于等待狀態(tài)的類:中斷處于等待狀態(tài)的Thread時(shí)引發(fā)的異常。時(shí)引發(fā)的異常。l ThreadStartException類:當(dāng)基礎(chǔ)操作系統(tǒng)線程已啟動(dòng)但該類:當(dāng)基礎(chǔ)操作系統(tǒng)線程已啟動(dòng)但該線程尚未準(zhǔn)備好執(zhí)行用戶代碼前,托管線程中出現(xiàn)錯(cuò)誤,則線程尚未準(zhǔn)備好執(zhí)行用戶代碼前,托管線程中出現(xiàn)錯(cuò)誤,則會(huì)引發(fā)異常。會(huì)引發(fā)異常。l ThreadStateException類:當(dāng)類:當(dāng)Thread處于對(duì)方法調(diào)用無(wú)效的處于對(duì)方法調(diào)用無(wú)效的ThreadState時(shí)引發(fā)的異常。時(shí)引發(fā)的異常。13.3.3 Thread類及其應(yīng)用類及其應(yīng)用1. Thread類類Thread類是最重要的線程類。類是最重要

46、的線程類。屬性屬性說(shuō)明說(shuō)明CurrentThread獲取當(dāng)前正在運(yùn)行的線程獲取當(dāng)前正在運(yùn)行的線程IsAlive獲取一個(gè)值,該值指示當(dāng)前線程的執(zhí)行狀態(tài)獲取一個(gè)值,該值指示當(dāng)前線程的執(zhí)行狀態(tài)IsBackground獲取或設(shè)置一個(gè)值,該值指示某個(gè)線程是否為后臺(tái)線程獲取或設(shè)置一個(gè)值,該值指示某個(gè)線程是否為后臺(tái)線程N(yùn)ame獲取或設(shè)置線程的名稱獲取或設(shè)置線程的名稱Priority獲取或設(shè)置一個(gè)值,該值指示線程的調(diào)度優(yōu)先級(jí)獲取或設(shè)置一個(gè)值,該值指示線程的調(diào)度優(yōu)先級(jí)ThreadState獲取一個(gè)值,該值包含當(dāng)前線程的狀態(tài)獲取一個(gè)值,該值包含當(dāng)前線程的狀態(tài)方法方法說(shuō)明說(shuō)明Abort在調(diào)用此方法的線程上引發(fā)在調(diào)用

47、此方法的線程上引發(fā)ThreadAbortException,以開(kāi)始終止此線,以開(kāi)始終止此線程的過(guò)程。調(diào)用此方法通常會(huì)終止線程程的過(guò)程。調(diào)用此方法通常會(huì)終止線程Interrupt中斷處于等待、休眠或聯(lián)接狀態(tài)的線程中斷處于等待、休眠或聯(lián)接狀態(tài)的線程Join阻塞調(diào)用線程,直到某個(gè)線程終止時(shí)為止。阻塞調(diào)用線程,直到某個(gè)線程終止時(shí)為止。t.Join()可以理解為把線程可以理解為把線程t放到當(dāng)前位置來(lái)執(zhí)行放到當(dāng)前位置來(lái)執(zhí)行,只有只有t結(jié)束以后才會(huì)執(zhí)行結(jié)束以后才會(huì)執(zhí)行t.Join()以后的代碼以后的代碼 Resume繼續(xù)已掛起的線程繼續(xù)已掛起的線程Sleep將當(dāng)前線程阻塞指定的毫秒數(shù)將當(dāng)前線程阻塞指定的毫秒

48、數(shù)Start使線程得以按計(jì)劃執(zhí)行使線程得以按計(jì)劃執(zhí)行Suspend掛起線程,或者如果線程已掛起,則不起作用。掛起線程,或者如果線程已掛起,則不起作用。2. 創(chuàng)建和啟動(dòng)新線程創(chuàng)建和啟動(dòng)新線程應(yīng)用程序執(zhí)行時(shí),將創(chuàng)建新的應(yīng)用程序域。當(dāng)執(zhí)行環(huán)應(yīng)用程序執(zhí)行時(shí),將創(chuàng)建新的應(yīng)用程序域。當(dāng)執(zhí)行環(huán)境調(diào)用應(yīng)用程序的入口點(diǎn)(境調(diào)用應(yīng)用程序的入口點(diǎn)(Main方法)時(shí),將創(chuàng)建應(yīng)用程方法)時(shí),將創(chuàng)建應(yīng)用程序的主線程。主線程以外的線程一般稱為序的主線程。主線程以外的線程一般稱為工作線程工作線程。Thread類的主要構(gòu)造函數(shù)如下:類的主要構(gòu)造函數(shù)如下:(1)public Thread(ThreadStart start)其中

49、,參數(shù)其中,參數(shù)start為為T(mén)hreadStart委托,它表示此線程開(kāi)委托,它表示此線程開(kāi)始執(zhí)行時(shí)要調(diào)用的方法。始執(zhí)行時(shí)要調(diào)用的方法。(2)public Thread(ParameterizedThreadStart start)其中,參數(shù)其中,參數(shù)start為為ParameterizedThreadStart委托,表委托,表示此線程開(kāi)始執(zhí)行時(shí)要調(diào)用的方法。它表示初始化示此線程開(kāi)始執(zhí)行時(shí)要調(diào)用的方法。它表示初始化Thread類的新實(shí)例,并指定允許對(duì)象在線程啟動(dòng)時(shí)傳遞給線程的類的新實(shí)例,并指定允許對(duì)象在線程啟動(dòng)時(shí)傳遞給線程的委托。委托。例如,有以下類:例如,有以下類:class MyClass

50、/聲明包含方法的類聲明包含方法的類public void method1()/不帶參數(shù)的方法不帶參數(shù)的方法method1public void method2(object data) /帶參數(shù)的方法帶參數(shù)的方法method2采用靜態(tài)方式創(chuàng)建和啟動(dòng)工作線程的過(guò)程如下:采用靜態(tài)方式創(chuàng)建和啟動(dòng)工作線程的過(guò)程如下:MyClass obj = new MyClass();/創(chuàng)建創(chuàng)建MyClass的實(shí)例的實(shí)例Thread workth1 = new Thread(obj.method1);/創(chuàng)建一個(gè)工作線程創(chuàng)建一個(gè)工作線程workth1workth1.Start();/啟動(dòng)工作線程啟動(dòng)工作線程workt

51、h1Thread workth2 = new Thread(obj.method1);/創(chuàng)建一個(gè)工作線程創(chuàng)建一個(gè)工作線程workth2workth1.Start(10);/啟動(dòng)工作線程啟動(dòng)工作線程workth2,其中,其中10為實(shí)參為實(shí)參delegate void deletype1();/聲明委托類型聲明委托類型deletype1delegate void deletype2(object obj);/聲明委托類型聲明委托類型deletype2deletype1 mydele1;/定義委托變量定義委托變量mydele1deletype2 mydele2;/定義委托變量定義委托變量mydele

52、2MyClass a = new MyClass();/創(chuàng)建創(chuàng)建MyClass類的實(shí)例類的實(shí)例mydele1 = new deletype1(a.method1);mydele2 = new deletype2(a.method2);Thread workth1 = new Thread(new ThreadStart(mydele1);/創(chuàng)建一個(gè)工作線程創(chuàng)建一個(gè)工作線程workth1workth1.Start();/啟動(dòng)工作線程啟動(dòng)工作線程workth1Thread workth2 = new Thread(new ParameterizedThreadStart(mydele2); /創(chuàng)建

53、一個(gè)工作線程創(chuàng)建一個(gè)工作線程workth2workth2.Start(10);/啟動(dòng)工作線程啟動(dòng)工作線程workth2,其中,其中10為實(shí)參為實(shí)參采用委托方式創(chuàng)建和啟動(dòng)工作線程的過(guò)程如下:采用委托方式創(chuàng)建和啟動(dòng)工作線程的過(guò)程如下:3. 暫停線程暫停線程一旦線程已啟動(dòng),就可以調(diào)用其方法來(lái)更改它的狀態(tài)。一旦線程已啟動(dòng),就可以調(diào)用其方法來(lái)更改它的狀態(tài)。例如,例如,通過(guò)調(diào)用通過(guò)調(diào)用Thread.Sleep()可以使線程暫停一段時(shí)間可以使線程暫停一段時(shí)間(以毫秒為單位)。其使用語(yǔ)法格式如下:(以毫秒為單位)。其使用語(yǔ)法格式如下:Thread.Sleep(n);其中其中n為掛起的毫秒數(shù),即線程保持鎖定狀態(tài)

54、的毫秒數(shù)。為掛起的毫秒數(shù),即線程保持鎖定狀態(tài)的毫秒數(shù)。如果使用參數(shù)如果使用參數(shù)Infinite調(diào)用調(diào)用Sleep,則會(huì)導(dǎo)致線程休眠,則會(huì)導(dǎo)致線程休眠,直至調(diào)用直至調(diào)用Interrupt的另一個(gè)線程將其喚醒為止。的另一個(gè)線程將其喚醒為止。 Thread.Sleep(Timeout.Infinite);4. 中斷線程中斷線程Interrupt()Interrupt()方法會(huì)將目標(biāo)線程從其可能處于的任何等方法會(huì)將目標(biāo)線程從其可能處于的任何等待狀態(tài)中喚醒,并導(dǎo)致引發(fā)待狀態(tài)中喚醒,并導(dǎo)致引發(fā)ThreadInterruptedException異異常。常。通過(guò)對(duì)被阻止的線程調(diào)用通過(guò)對(duì)被阻止的線程調(diào)用Int

55、errupt()方法可以中斷正方法可以中斷正在等待的線程,從而使該線程脫離造成阻止的調(diào)用。在等待的線程,從而使該線程脫離造成阻止的調(diào)用。 線程應(yīng)該捕獲線程應(yīng)該捕獲ThreadInterruptedException異常并執(zhí)行異常并執(zhí)行任何適當(dāng)?shù)牟僮饕岳^續(xù)運(yùn)行。如果線程忽略該異常,則運(yùn)任何適當(dāng)?shù)牟僮饕岳^續(xù)運(yùn)行。如果線程忽略該異常,則運(yùn)行庫(kù)將捕獲該異常并停止該線程。行庫(kù)將捕獲該異常并停止該線程。5. 銷毀線程銷毀線程Abort()Abort()方法用于永久地停止托管線程。調(diào)用方法用于永久地停止托管線程。調(diào)用Abort時(shí),時(shí),公共語(yǔ)言運(yùn)行庫(kù)在目標(biāo)線程中引發(fā)公共語(yǔ)言運(yùn)行庫(kù)在目標(biāo)線程中引發(fā)ThreadA

56、bortException,目標(biāo)線程可捕捉此異常。目標(biāo)線程可捕捉此異常。Abort()方法不直接導(dǎo)致線程中止,因?yàn)槟繕?biāo)線程可捕捉方法不直接導(dǎo)致線程中止,因?yàn)槟繕?biāo)線程可捕捉ThreadAbortException并在并在finally塊中執(zhí)行任意數(shù)量的代碼。塊中執(zhí)行任意數(shù)量的代碼。 如果需要等待線程結(jié)束,可調(diào)用如果需要等待線程結(jié)束,可調(diào)用Join()方法。方法。Thread.Join()是一種模塊化調(diào)用,它在線程實(shí)際停止執(zhí)行之是一種模塊化調(diào)用,它在線程實(shí)際停止執(zhí)行之前,或可選超時(shí)間隔結(jié)束之前不會(huì)返回。等待對(duì)前,或可選超時(shí)間隔結(jié)束之前不會(huì)返回。等待對(duì)Join()方法方法的調(diào)用的線程可由其他線程調(diào)用

57、的調(diào)用的線程可由其他線程調(diào)用Interrupt()來(lái)中斷。來(lái)中斷。注意:一旦線程被中止,它將無(wú)法重新啟動(dòng)。如果線注意:一旦線程被中止,它將無(wú)法重新啟動(dòng)。如果線程已經(jīng)在中止,則不能通過(guò)程已經(jīng)在中止,則不能通過(guò)Start()來(lái)啟動(dòng)線程。來(lái)啟動(dòng)線程。線程狀態(tài)關(guān)系圖線程狀態(tài)關(guān)系圖 WaitSleepJoin:線程因?yàn)檎{(diào)用了:線程因?yàn)檎{(diào)用了Wait(),Sleep()或或Join()等方法處于封鎖狀態(tài)等方法處于封鎖狀態(tài) Stopped:線程已經(jīng)被停止:線程已經(jīng)被停止 Running:線程正:線程正在正常運(yùn)行在正常運(yùn)行 AbortRequested:線:線程的程的Thread.Abort()方方法已被調(diào)用

58、,但是線法已被調(diào)用,但是線程還未停止程還未停止 Aborted:線程已停止:線程已停止 InterruptSleep,Joinusing System; using System.Threading;class ThreadTest static void Main() Thread t = new Thread (WriteY); t.Start(); / Run WriteY on the new thread while (true) Console.Write (x); / Write x forever static void WriteY() while (true) Consol

59、e.Write (y); / Write y forever 主線程創(chuàng)建了一個(gè)新線程主線程創(chuàng)建了一個(gè)新線程“t”,它運(yùn)行了一個(gè)重復(fù)打,它運(yùn)行了一個(gè)重復(fù)打印字母印字母y的方法,同時(shí)主線程重復(fù)打印字母的方法,同時(shí)主線程重復(fù)打印字母“x”。CLR分分配每個(gè)線程到它自己的內(nèi)存堆棧上,來(lái)保證局部變量的分配每個(gè)線程到它自己的內(nèi)存堆棧上,來(lái)保證局部變量的分離運(yùn)行。離運(yùn)行。 【例【例13.4】 分析以下程序的執(zhí)行結(jié)果。分析以下程序的執(zhí)行結(jié)果。using System;using System.Threading;/新增引用新增引用namespace Proj13_4public class Apublic v

60、oid fun()/定義類定義類A的方法的方法while (true) Console.WriteLine(工作線程工作線程:正在執(zhí)行正在執(zhí)行A.fun方法方法.); ;public class Programpublic static void Main() Console.WriteLine(主線程啟動(dòng)主線程啟動(dòng).);A a = new A();/創(chuàng)建創(chuàng)建A類的實(shí)例類的實(shí)例 Thread workth = new Thread(new ThreadStart(a.fun); /創(chuàng)建一個(gè)線程,使之執(zhí)行創(chuàng)建一個(gè)線程,使之執(zhí)行A類的類的fun()方法方法 Console.WriteLine(工作

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論