| 多線(xiàn)程在Visual C#網(wǎng)絡(luò )編程中的應用 |
| 網(wǎng)絡(luò )應用程序的一般都會(huì )或多或少的使用到線(xiàn)程,甚至可以說(shuō),一個(gè)功能稍微強大的網(wǎng)絡(luò )應用程序總會(huì )在其中開(kāi)出或多或少的線(xiàn)程,如果應用程序中開(kāi)出的線(xiàn)程數目大于二個(gè),那么就可以把這個(gè)程序稱(chēng)之為多線(xiàn)程應用程序。那么為什么在網(wǎng)絡(luò )應用程序總會(huì )和線(xiàn)程交纏在一起呢?這是因為網(wǎng)絡(luò )應用程序在執行的時(shí)候,會(huì )遇到很多意想不到的問(wèn)題,其中最常見(jiàn)的是網(wǎng)絡(luò )阻塞和網(wǎng)絡(luò )等待等。 程序在處理這些問(wèn)題的時(shí)候往往需要花費很多的時(shí)間,如果不使用線(xiàn)程,則程序在執行時(shí)的就會(huì )表現出如運行速度慢,執行時(shí)間長(cháng),容易出現錯誤、反應遲鈍等問(wèn)題。而如果把這些可能造成大量占用程序執行時(shí)間的過(guò)程放在線(xiàn)程中處理,就往往能夠大大提高應用程序的運行效率和性能和獲得更優(yōu)良的可伸縮性。那么這是否就意味著(zhù)應該在網(wǎng)絡(luò )應用程序中廣泛的使用線(xiàn)程呢?情況并非如此,線(xiàn)程其實(shí)是一把雙刃劍,如果不分場(chǎng)合,在不需要使用的地方強行使用就可能會(huì )產(chǎn)生許多程序垃圾,或者在程序結束后,由于沒(méi)有能夠銷(xiāo)毀創(chuàng )建的進(jìn)程而導致應用程序掛起等問(wèn)題。 所以如果你認為自己編寫(xiě)的代碼足夠快,那我給你的建議還是別使用線(xiàn)程或多線(xiàn)程。這里要提醒諸位的是如果您對在Windows下的線(xiàn)程和其執行原理和機制還不十分清楚,可以先參閱一下介紹Windows操作系統方面的書(shū)籍,它們一般都會(huì )對其進(jìn)行比較詳細的闡述。然后再閱讀本文。 一.簡(jiǎn)介在Visual C#中創(chuàng )建和使用線(xiàn)程: Visual C#中使用的線(xiàn)程都是通過(guò)自命名空間System.Threading中的Thread類(lèi)經(jīng)常實(shí)例化完成的。通過(guò)Thread類(lèi)的構造函數來(lái)創(chuàng )建可供Visual C#使用的線(xiàn)程,通過(guò)Thread中的方法和屬性來(lái)設定線(xiàn)程屬性和控制線(xiàn)程的狀態(tài)。以下Thread類(lèi)中的最典型的構造函數語(yǔ)法,在Visual C#中一般使用這個(gè)構造函數來(lái)創(chuàng )建、初始化Thread實(shí)例。 public Thread ( ThreadStart start ) ; 參數 start ThreadStart 委托,它將引用此線(xiàn)程開(kāi)始執行時(shí)要調用的方法。 Thread還提供了其他的構造函數來(lái)創(chuàng )建線(xiàn)程,這里就不一一介紹了。表01是Thread類(lèi)中的一些常用的方法及其簡(jiǎn)要說(shuō)明: 方法 說(shuō)明 Abort 調用此方法通常會(huì )終止線(xiàn)程,但會(huì )引起ThreadAbortException類(lèi)型異常。 Interrupt 中斷處于WaitSleepJoin 線(xiàn)程狀態(tài)的線(xiàn)程。 Join 阻塞調用線(xiàn)程,直到某個(gè)線(xiàn)程終止時(shí)為止。 ResetAbort 取消當前線(xiàn)程調用的Abor方法。 Resume 繼續已掛起的線(xiàn)程。 Sleep 當前線(xiàn)程阻塞指定的毫秒數。 Start 操作系統將當前實(shí)例的狀態(tài)更改為T(mén)hreadState.Running。 Suspend 掛起線(xiàn)程,或者如果線(xiàn)程已掛起,則不起作用。 表01:Thread類(lèi)的常用方法及其說(shuō)明 這里要注意的是在.Net中執行一個(gè)線(xiàn)程,當線(xiàn)程執行完畢后,一般會(huì )自動(dòng)銷(xiāo)毀。如果線(xiàn)程沒(méi)有自動(dòng)銷(xiāo)毀可通過(guò)Thread中的Abort方法來(lái)手動(dòng)銷(xiāo)毀,但同樣要注意的是如果線(xiàn)程中使用的資源沒(méi)有完全銷(xiāo)毀,Abort方法執行后,也不能保證線(xiàn)程被銷(xiāo)毀。在Thread類(lèi)中還提供了一些屬性用以設定和獲取創(chuàng )建的Thread實(shí)例屬性,表02中是Thread類(lèi)的一些常用屬性及其說(shuō)明: 屬性 說(shuō)明 CurrentCulture 獲取或設置當前線(xiàn)程的區域性。 CurrentThread 獲取當前正在運行的線(xiàn)程。 IsAlive 獲取一個(gè)值,該值指示當前線(xiàn)程的執行狀態(tài)。 IsBackground 獲取或設置一個(gè)值,該值指示某個(gè)線(xiàn)程是否為后臺線(xiàn)程。 Name 獲取或設置線(xiàn)程的名稱(chēng)。 Priority 獲取或設置一個(gè)值,該值指示線(xiàn)程的調度優(yōu)先級。 ThreadState 獲取一個(gè)值,該值包含當前線(xiàn)程的狀態(tài)。 表02:Thread類(lèi)的常用屬性及其說(shuō)明 二.本文的主要內容及程序調試和運行環(huán)境: 本文的主要內容是介紹多線(xiàn)程給用Visual C#編寫(xiě)網(wǎng)絡(luò )應用程序帶來(lái)的更高性能提高。具體的做法是在Visual C#用二種不同的方法,一種采用了多線(xiàn)程,另一種不是,來(lái)實(shí)現同一個(gè)具體網(wǎng)絡(luò )應用示例,此示例的功能是獲取網(wǎng)絡(luò )同一網(wǎng)段多個(gè)IP地址對應的計算機的在線(xiàn)狀態(tài)和對應的計算機名稱(chēng),通過(guò)比較這二種方法的不同執行效率就可知多線(xiàn)程對提高網(wǎng)絡(luò )應用程序的執行效率是多么的重要了。以下是本文中設計到程序的調試和運行的基本環(huán)境配置: (1).微軟公司視窗2000服務(wù)器版。 (2).Visual Studio .Net 2002正式版,.Net FrameWork SDK版本號3705。 三.掃描網(wǎng)絡(luò )計算機的原理 : 下面介紹的這個(gè)示例的功能是通過(guò)掃描一個(gè)給定區間IP地址,來(lái)判斷這些IP地址對應的計算機是否在線(xiàn),如果在線(xiàn)則獲得IP地址對應的計算機名稱(chēng)。程序判斷計算機是否在線(xiàn)的是采用對給定IP地址的計算機進(jìn)行DNS解析,如果能夠根據IP地址解析出對應的計算機名稱(chēng),則說(shuō)明此IP地址對應的計算機在線(xiàn);反之,如果解析不出,則會(huì )產(chǎn)生異常出錯,通過(guò)對異常的捕獲,得到此IP地址對應的計算機并不在線(xiàn)。 為了更清楚地說(shuō)明問(wèn)題和便于掌握在Visual C#編寫(xiě)多線(xiàn)程網(wǎng)絡(luò )應用程序的方法,本文首先介紹的是不基于多線(xiàn)程的網(wǎng)絡(luò )計算機掃描程序的編寫(xiě)步驟,然后再在其基礎上,把它修改成多線(xiàn)程的計算機掃描程序,最后比較這二個(gè)程序的執行效率,你就會(huì )發(fā)現線(xiàn)程在網(wǎng)絡(luò )編程中的重要作用了。 四.Visual C#實(shí)現不基于多線(xiàn)程的網(wǎng)絡(luò )計算機掃描程序 以下是在Visual C#實(shí)現不基于多線(xiàn)程的網(wǎng)絡(luò )計算機掃描程序步驟: 1. 啟動(dòng)Visual Studio .Net,并新建一個(gè)Visual C#項目,項目名稱(chēng)為【掃描網(wǎng)絡(luò )計算機】。 2. 把Visual Studio .Net的當前窗口切換到【Form1.cs(設計)】窗口,并從【工具箱】中的【W(wǎng)indows窗體組件】選項卡中往Form1窗體中拖入下列組件,并執行相應操作: 四個(gè)NumericUpDown組件,用以組合成一個(gè)IP地址區間。 一個(gè)ListBox組件,用以顯示掃描后的結果。 一個(gè)ProgressBar組件,用以顯示程序的運行進(jìn)度。 四個(gè)Label組件,用以顯示提示信息。 一個(gè)GroupBox組件。 一個(gè)Button組件,名稱(chēng)為button1,并在這組件拖入窗體后,雙擊button1,這樣Visual Studio .Net就會(huì )產(chǎn)生這button1組件Click事件對應的處理代碼。 界面設置如下圖: ![]() 圖01:【掃描網(wǎng)絡(luò )計算機】項目的設計界面 3. 把Visual Studio .Net的當前窗口切換到【Form1.cs】,進(jìn)入Form1.cs文件的編輯界面。在Form1.cs頭部,用下列代碼替換系統缺省的導入命名空間代碼: using System ; using System.Drawing ; using System.Collections ; using System.ComponentModel ; using System.Windows.Forms ; using System.Data ; using System.Net.Sockets ; using System.Net ; 4. 用下列代碼替換Form1.cs中的button1的Click時(shí)間對應的處理代碼,下列代碼的功能是掃描給定的IP地址區間,并把掃描結果顯示出來(lái)。 private void button1_Click ( object sender , System.EventArgs e ) { listBox1.Items.Clear ( ) ; //清楚掃描結果顯示區域 DateTime StartTime = DateTime.Now ; //獲取當前時(shí)間 string mask = numericUpDown1.Value.ToString ( ) + "." + numericUpDown2.Value.ToString ( ) + "." + numericUpDown3.Value.ToString ( ) + "." ; int Min = ( int ) numericUpDown4.Value ; int Max = ( int ) numericUpDown5.Value ; if ( Min > Max ) { MessageBox.Show ( "輸入的IP地址區間不合法,請檢查!" , "錯誤!" ) ; return ; } //判斷輸入的IP地址區間是否合法 progressBar1.Minimum = Min ; progressBar1.Maximum = Max ; int i ; for ( i = Min ; i <= Max ; i++ ) { string ip= mask + i.ToString ( ) ; IPAddress myIP = IPAddress.Parse ( ip ) ; //根據給定的IP地址字符串,處境IPAddress實(shí)例 try { IPHostEntry myHost = Dns.GetHostByAddress ( myIP ) ; string HostName = myHost.HostName.ToString ( ) ; |
聯(lián)系客服