• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    在你的VB.NET應用程序中使用多線程

    發布: 2007-7-14 20:28 | 作者: 佚名    | 來源: 網絡轉載     | 查看: 13次 | 進入軟件測試論壇討論

    領測軟件測試網    很長時間以來,開發人員一直要求微軟為VB增加更多的線程功能——這一點在VB.NET中終于實現了。VB6不支持創建多線程的EXE、DLL以及OCX。但這種措詞容易引起誤解,這是因為VB6支持執行多個單線程的單元。一個單元實際上是代碼執行的場所而且單元的邊界限制了外部代碼對單元內部的訪問。

       VB.NET支持創建自由線程的應用程序。這意味著多個線程可以訪問同一個共享的數據集。本文將帶領你了解多線程的基本內容。

    雖然VB支持多個單線程的單元,但并不支持允許多個線程在同一個數據集上運行的自由線程模型。在很多情況下,產生一個運行后臺處理程序的新線程會提高應用程序的可用性。一種很顯然的情況就是當執行一個可能使窗體看起來停止響應的長過程時,你一定會想在窗體上放置一個取消按鈕。

    解決方法

    由于VB.NET使用公共語言運行時(Common Language Runtime),它增強了很多新的特性,其中之一便是創建自由線程應用程序的能力。

    在VB.NET中,開始使利用線程進行工作是很容易的。稍后我們會探究一些精妙之處,我們先創建一個簡單的窗體,它生成一個執行后臺處理程序的新線程。我們需要做的第一件事是將要在新線程上運行的后臺處理程序。下面的代碼執行一個相當長的運行過程——一個無限循環:

    Private Sub BackgroundProcess()

        Dim i As Integer = 1

        Do While True

            ListBox1.Items.Add("Iterations: " + i)

            i += 1

        Loop

    End Sub

    這段代碼無限地循環并在每次循環中向窗體上的列表框中增加一個條目。如果你對VB.NET不熟悉的話,便會發現這段代碼中有一些在VB6中無法完成的事:

    l          在聲明變量時對其賦值 Dim i As Integer=1

    l          使用+=操作符 i+=1代替了i=i+1

    l          Call關鍵字已經被去除了

    一旦我們有了一個工作過程,便需要將這段代碼指派給一個新的線程并開始它的執行。完成這項工作,我們需要使用Thread對象,它是.NET框架類中System.Threading命名空間的一部分。當實例化了一個新的Thread類時,我們向其傳遞一個引用,這個引用指向我們想要在Thread類的構造函數中執行的代碼塊。下面的代碼創建一個新的Thread對象并將指向BackgroundProcess的引用傳遞給它:

    Dim t As Thread

    t = New Thread(AddressOf Me.BackgroundProcess)

    t.Start()

    AddressOf操作符為BackgroundProcess方法創建了一個委派對象。委派在VB.NET中是一種類型安全的、面向對象的函數指針。在線程被實例化之后,你可以通過調用線程的Start()方法開始執行代碼。

    使線程處于控制之下

    當線程開始之后,你可以通過使用Thread對象的方法對其狀態進行一定的控制。你可以通過調用Thread.Sleep方法暫停線程的執行。這個方法接收一個表示線程將要休眠多長時間的整型數值。如果在上例中你想要減緩列表框條目的添加,在代碼中放置一個對此方法的調用:

    Private Sub BackgroundProcess()

        Dim i As Integer = 1

        Do While True

            ListBox1.Items.Add("Iterations: " + i)

            i += 1

            Thread.CurrentThread.Sleep(2000)

        Loop

    End Sub

    CurrentThread是一個公共靜態屬性,它可以使你獲取一個對當前運行線程的引用。

    你還可以通過調用Thread.Sleep (System.Threading.Timeout.Infinite)使一個線程處于一種時間不確定的休眠狀態。要中斷這種休眠,可以調用Thread.Interrupt 方法。

    類似與Sleep和Interrupt的是Suspend和Resume。Suspend允許你阻塞一個線程直到另外的線程調用Thread.Resume。Sleep和Suspend之間的區別在于后者不是立即使一個線程處于等待狀態。在.NET運行時確定線程是處于一個安全的掛起位置之前,線程是不會掛起的。Sleep則是立即使線程進入等待狀態。

    最后,Thread.Abort中止一個線程的執行。在我們的簡單例子中,我們還想增加另外一個可以使我們中止程序的按鈕。要完成這些,我們所需做的一切便是如下面這樣調用Thread.Abort方法:

    Private Sub Button2_Click(ByVal sender As System.Object, _

            ByVal e As System.EventArgs) Handles Button2.Click

        t.Abort()

    End Sub

    在此便可以看出多線程的能力。用戶界面看起來對用戶是有響應的,因為它運行在一個線程中而后臺的處理程序運行在另一個線程中。取消按鈕會立即響應用戶的click事件同時處理過程被中止。

    通過多線程的過程傳遞數據

    上一個例子展示了一種相當簡單的情況。在你編程的時候,多線程有很多需要解決的復雜問題。你將會遇到的一個問題是向傳遞給Thread類構造函數的過程傳遞數據以及從這個過程傳出數據。換言之,你想要在另一個線程上開始的過程不能接收任何參數而且你也不能從這個過程返回任何數據。這是因為傳遞給線程構造函數的過程不能有任何參數或返回值。為了避開這個問題,將你的過程包裝到一個類中,在這個類中此方法的參數被表示成類的一個域。

    有一個簡單的例子,如果我們有一個計算一個數的平方的過程:

    Function Square(ByVal Value As Double) As Double

        Return Value * Value

    End Function

    為了使這個過程可以在一個新線程中使用,我們將其包裝到一個類中:

    Public Class SquareClass

        Public Value As Double

        Public Square As Double

        Public Sub CalcSquare()

            Square = Value * Value

        End Sub

    End Class

    使用這些代碼在一個新線程中啟動CalcSquare過程,代碼如下:

    Private Sub Button1_Click(ByVal sender As System.Object, _

            ByVal e As System.EventArgs) Handles Button1.Click

        Dim oSquare As New SquareClass()

        t = New Thread(AddressOf oSquare.CalcSquare)

        oSquare.Value = 30

        t.Start()

    End Sub

    注意當線程開始后,我們沒有檢查類的平方值,因為并不能保證一旦你調用線程Start方法,它便會執行。有一些方法可以從另外的線程中獲取這個值。最簡單的方法是當線程完成時引發一個事件。我們會在下一個部分線程同步中討論另外一種方法。下面的代碼為SquareClass增加了事件聲明。

    Public Class SquareClass

        Public Value As Double

        Public Square As Double

        Public Event ThreadComplete(ByVal Square As Double)

        Public Sub CalcSquare()

            Square = Value * Value

            RaiseEvent ThreadComplete(Square)

        End Sub

    End Class

    在調用代碼中捕獲這個事件與VB6相比沒有太大的變化,仍然是用WithEvents聲明變量并在一個過程中處理事件。變化的部分是用Handles關鍵字聲明處理事件的過程并且不再使用像VB6中Object_Event的命名約定。

    Dim WithEvents oSquare As SquareClass



    Private Sub Button1_Click(ByVal sender As System.Object, _

            ByVal e As System.EventArgs) Handles Button1.Click

        oSquare = New SquareClass()

        t = New Thread(AddressOf oSquare.CalcSquare)

        oSquare.Value = 30

        t.Start()

    End Sub



    Sub SquareEventHandler(ByVal Square As Double) _

            Handles oSquare.ThreadComplete

        MsgBox("The square is " & Square)

    End Sub

    這個方法需要注意的一個問題是處理事件的過程,在本例中是SquareEventHandler,將運行在引發事件的線程中,而不是運行在窗體從中執行的線程中。

    線程同步

    VB.NET包含了一些語句用于提供線程的同步。在Square的例子中,你可能想同步執行計算的線程以便等到計算完成,這樣便可以獲得結果。舉另外一個例子,如果你在一個單獨的線程中對數組進行排序并且在使用這個數組之前要等待這個處理過程結束。為了實現這些同步,VB.NET提供了SyncLock語句和Thread.Join方法。

    SyncLock獲取了對傳遞給它的對象引用的獨占性鎖。通過取得這種獨占鎖,你可以確保多個線程不會訪問共享的數據或是在多個線程上執行代碼。一個可以方便地用于獲取鎖地對象是關聯于每個類的System.Type對象?梢酝ㄟ^GetType方法獲得System.Type對象:

    Public Sub CalcSquare()

        SyncLock GetType(SquareClass)

            Square = Value * Value

        End SyncLock

    End Sub

    最后,Thread.Join方法允許你等待一段特定的時間直到一個線程結束。如果線程在你所確定的時間之前完成,Thread.Join返回True,否則的話返回False。在Square的例子中,如果我們不想引發事件,可以調用Thread.Join方法來確定計算是否已經結束。代碼如下所示:

    Private Sub Button1_Click(ByVal sender As System.Object, _

            ByVal e As System.EventArgs) Handles Button1.Click

        Dim oSquare As New SquareClass()

        t = New Thread(AddressOf oSquare.CalcSquare)

        oSquare.Value = 30

        t.Start()

        If t.Join(500) Then

            MsgBox(oSquare.Square)

        End If

    End Sub



    作者:Matthew Arnheiter是位于哈肯薩克市(Hackensack)的GoAmerica Communications公司的一名資深顧問,他還是The Visual Basic Developer's Guide to Design Patterns and UML (Sybex, 2000)一書的作者?梢酝ㄟ^(201)996-1717 x2367或Marnheiter◎goamerica.net與他取得聯系。

    文章來源于領測軟件測試網 http://www.kjueaiud.com/


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備10010545號-5
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>