基於VB.NET的多線程編程實現

基於VB.NET的多線程編程實現
  摘 要 Visaul Basic 在6.0之前的版本中對多線程並沒有提供一個很好的支持,而微軟的.NET框架提供了新的類庫,從而可以方便地創建多線程應用程序。 本文首先概述了進程、線程以及應用程序域的相互關係,隨後介紹瞭如何使用Visual Basic.NET的多線程編程技術來開發效率更高,響應速度更快的應用程序。

  關鍵詞 .NET框架 Visual Basic.NET 多線程 同步

  1. 引言

  1.1 進程與線程和應用程序域

  在操作系統中,進程被定義爲應用程序的運行實例,是應用程序的一次動態執行。線程是進程內部程序執行的路徑,是進程的一個執行單元。從根本上說,線程是可由系統調度的一個最簡單的代碼單元,負責執行包含在進程的地址空間中的程序代碼。參見圖1。

  在.NET框架中,提出了應用程序域的概念。所有程序編譯後生成的都是中間代碼,而這些中間代碼的隔離、加載和卸載以及安全邊界的提供都是通過應用程序域來實現的。此時,一個進程可以包含一個或多個應用程序域,而一個應用程序域又可以包含一個或多個線程。這樣實際上就相當於在進程和線程之間增加了一個新的安全邊界。無論在同一個進程之內還是在不同的進程之間,每個應用程序域之間都是相互無關的,這些不同的應用程序域之間只能通過遠程通訊來實現消息和對象的傳遞。

基於VB.NET的多線程編程實現
圖1 進程、線程和應用程序域之間的關係

  1.2 多線程的意義

  一個採用了多線程技術的應用程序可以更好地利用系統資源。其主要優勢在於充分利用了CPU的空閒時間片,可以用儘可能少的時間來對用戶的要求做出響應,使得進程的整體運行效率得到較大提高,同時增強了應用程序的靈活性。更爲重要的是,由於同一進程的所有線程是共享同一內存,所以不需要特殊的數據傳送機制,不需要建立共享存儲區或共享文件,從而使得不同任務之間的協調操作與運行、數據的交互、資源的分配等問題更加易於解決。

  2. Visual basic.net對多線程的支持

  2.1 VB對多線程的支持

  在舊有的VB6.0及其以前的版本中,較少涉及到多線程的問題。這是因爲VB並不是線程安全的,多線程模式的工作原理和編程機制對於VB並不完全適合。在VB6.0的應用中,我們可以通過Win32 CreateThread API來創建一個多線程的應用,或者通過欺騙COM庫而在一個獨立的線程中創建一個組件,不過這些技術都是難以調試和維護的。

  2.2 Visual Basic.NET對多線程的支持

  由於Visual Basic.NET是基於.NET框架的,而.NET框架的重要組成部分CLR(Common Language Runtime,通用語言運行時)內置支持多線程應用,可以通過系統的System.Threading類直接建立多線程應用程序,並且支持線程池等高級功能。任何.NET框架結構下的語言,包括Visual Basic.NET在編寫多線程應用程序的時候,都可以利用系統類所提供的對象和方法,而不再需要使用Win32 API,因此可以大大減輕開發的困難和錯誤所發生的機率。 3. Visual Basic.NET中多線程編程的實現

  3.1 線程的創建與管理

  用來創建和維護線程的基類是System.Threading.Thread類。它能夠創建並控制線程,設置其優先級並獲取其狀態。它擁有Start, Stop, Resume, Abort, Suspend和Join (wait for)等方法操縱線程,還可以通過如Sleep, IsAlive, IsBackground, Priority, ApartmentState和ThreadState等方法查詢和設置線程狀態。

  最直接的創建線程的方法是創建一個新的線程類實例,並使用AddressOf語句爲要運行的線程傳遞任務。

  以下代碼將名爲myTask的子過程作爲單獨的線程運行:

Dim Thread1 As New System.Threading.Thread(AddressOf myTask)

Thread1.Start

  類似的,使用Thread類的Sleep方法可以阻滯當前線程,使用Suspend方法可以掛起線程,使用Resume可以重新啓動掛起的線程,使用Abort方法可以停止一個線程,使用Join方法可以使當前線程等待其它線程運行結束。

  3.2 線程取消

  多線程的一個優點是,應用程序的用戶界面部分始終可以做出響應,即使其它線程正在執行任務。通過同步事件和作爲標誌的字段可以通知其它線程停止。要取消一個或多個正在運行的線程,可以調用 CancelTask() 方法。

  3.3 線程的優先級

  不同的線程具有不同的優先級,而優先級決定了線程能夠得到多少CPU時間。高優先級的線程通常會比一般優先級的線程得到更多的CPU時間,如果程序中存在不止一個高優先級的線程,操作系統將在這些線程之間循環分配CPU時間。一旦低優先級的線程在執行時遇到了高優先級的線程,它將讓出CPU給高優先級的線程。在Visual Basic.NET中,System.Threading.Thread.Priority枚舉了線程的優先級別,這些級別包括Highest、AboveNormal、Normal、BelowNormal、Lowest。新創建的線程初始優先級爲Normal。

  3.4 線程的狀態

  線程從創建到終止,它一定處於某一個狀態,而這個狀態是由System.Threading.Thread.ThreadState屬性定義的。當一個線程剛被創建時,它處在Unstarted狀態,然後Thread類的Start() 方法將使線程狀態變爲Running狀態,如果不調用相應的方法使線程掛起、阻塞、銷燬或者終止,則線程將一直保持這樣的狀態。掛起的線程處於Suspended狀態,直到我們調用resume()方法使其重新執行,這時候線程將重新變爲Running狀態。一旦線程被銷燬或者終止,則線程處於Stopped狀態,處於這個狀態的線程將不復存在。線程還有一個Background狀態,它表明線程運行在前臺還是後臺。而在一個確定的時間,線程可能處於多個狀態。參見圖2。

基於VB.NET的多線程編程實現
圖2 線程狀態轉換

  3.5 線程池

  在應用程序中使用多線程操作能優化應用程序性能,但是多線程往往需要花費更多的代碼和精力去控制線程以及實現線程之間的輪詢和狀態轉換。使用線程池則可以自動完成這些工作,同時還可以優化計算機的訪問性能,從而更加有效的利用多線程的優勢。使用線程池,可以使用要運行的過程的委託來調用 ThreadPool.QueueUserWorkItem 方法,VB .NET 將創建線程並運行該過程。以下代碼說明了如何使用線程池啓動多個任務。

Sub DoMyWork()

Dim MyPool As System.Threading.ThreadPool ' 將一個任務排隊

MyPool.QueueUserWorkItem(New System.Threading.WaitCallback(AddressOf Task1))

MyPool.QueueUserWorkItem(New System.Threading.WaitCallback(AddressOf Task2))

End Sub

  如果要啓動很多單獨的任務,但並不需要單獨設置每個線程的屬性,則線程池將非常有用。每個線程都以默認的堆棧大小和優先級啓動。默認情況下,每個系統處理器上最多可以運行25個線程池線程。超過該限制的其它線程會被排隊,直至其它線程運行結束後它們才能開始運行。

  線程池並不是在所有的情況下都適用,當需要特定優先級的線程時就沒法通過線程池來實現。

  3.6 線程的同步

  在多線程應用中,我們需要考慮不同線程之間的數據同步和防止死鎖。當兩個或多個線程之間同時等待對方釋放資源的時候就會形成線程之間的死鎖。爲了防止死鎖的發生,我們需要通過同步來實現線程安全。在Visual Basic.NET中提供了三種方法來完成線程的同步。

  (1) 代碼域同步:使用Monitor類可以同步靜態/實例化的方法的全部代碼或者部分代碼段。

  (2) 手工同步:可以使用不同的同步類(諸如WaitHandle, Mutex, ReaderWriterLock, ManualResetEvent, AutoResetEvent 和Interlocked等)創建自己的同步機制。這種同步方式要求你自己手動的爲不同的域和方法同步,這種同步方式也可以用於進程間的同步和解除由於對共享資源的等待而造成的死鎖。

  (3) 上下文同步:使用SynchronizationAttribute爲ContextBoundObject對象創建簡單的,自動的同步。這種同步方式僅用於實例化的方法和域的同步。所有在同一個上下文域的對象共享同一個鎖。

  4. 結束語

  本文討論了Visual Basic.NET中多線程開發技術。多線程技術是實現需要併發執行的應用程序的較好選擇,尤其對於大部分時間被阻塞的程序段,例如在開發訪問網絡資源,系統開銷比較大的操作或實現快速的用戶界面響應時,具有不可替代的作用。但由於每個線程都需要額外的內存來創建,同時還需要處理器時間片來運行和管理線程,因此如果創建的線程過多,反而會降低應用程序的性能。所以在設計多線程應用程序時,應慎重對待,建立合理的系統模型,這樣才能使應用程序獲得最佳的性能。     
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章