VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > VB.net教程 >
  • VB.Net的多线程及委托

一、多线程:在一个程序中,这些独立运行的程序片断叫作“线程”(Thread),利用它编程的概念就叫作“多线程处理”。多线程处理一个常见的例子就是用户界面。利用线程,用户可按下一个按钮,然后程序会立即作出响应,而不是让用户等待程序完成了当前任务以后才开始响应。用多线程的目的就是提高应用程序对事务处理能力,当程序在处理一个事务时,你还可以再做其它的事。

       1、定义:线程定义比较简单

DimTd As System.Threading.Thread

     2、实例化

        Td= NewSystem.Threading.Thread(AddressOf  过程名)

     3、执行

        Td.Start()

下面看一段代码:

DimTd AsSystem.Threading.Thread '定义一个线程

Dim Td = NewSystem.Threading.Thread(AddressOfabc)

Sub abc()

       Dim n as Int32=0

       For n = 0 To 100000000

                 System.Threading.Thread.Sleep(10) '让它走慢一点

       Next

End Sub

    PrivateSub Button1_Click(ByVal sender AsSystem.Object, ByValAs System.EventArgs) Handles Button1.Click

 

        Td = NewSystem.Threading.Thread(AddressOf abc) '实例化,指向abc过程

        Td.Start() '开始运行线程

EndSub

上面的代码就是一个简单的线程实例,这里有几个关于线程的命令,列举下面

命令              含义 

Start             引起线程开始运行

Sleep             暂停线程一段时间。格式:Thread.Sleep(毫秒数)

Suspend           线程到达安全点时暂停线程

Abort             停止线程

Resume            重新启动暂停的线程

Join              引起当前线程等待另一个线珵结果

上面的大多简单易懂,但是安全点(safe point)的概念对你来说可能是新的。安全点是代码中的某个位置,在这个位置通用语言运行时可以安全地执行自动无用单元收集(garbage collection,释放无用变量并恢复内存的过程)。当调用线程的AbortSuspend方法时,通用语言运行时分析代码,决定线程停止运行的适当位置。

下表是线程常用属性:

属性               值

IsAlive           如果线程是活动的,值为True

IsBackgroud       获取或设置一个布尔值,表示某个线程是否允许是后台线程

Name              获取或设置线程的名称

Priority          获取或设置一个操作系统用于区分线程调用的优先级

ApartmentState    获取或设置特定线程使用的线程模型

ThreadState       包含描述线程状态的值

二、委托

    在上面的实例中,在过程abc中添加一条语句:

           TextBox1.Text=n.ToString

就会出现一条错误信息:“线程间操作无效从不是创建控件“TextBox1”的线程访问它。”

这种错误解决方法在MSDN上提到三种,我们常用的是二种,没到MSDN上的第三种看过,我们只说前二种:

1、是在构造函数或者窗体Load的代码里添加下面一句: 

Control.CheckForIllegalCrossThreadCalls = False

这种不是用委托。

很简单,如果你是一个线程对某一控件操作,这种方法没问题,如果是多个线程对一个控件操作,这可能造成假死,窗体无反应,就是死锁现象。我们强烈建议你用委托。

   2、委托(Delegate

      委托的定义:

Delegate 语句定义委托类的参数和返回类型。任何具有匹配参数和返回类型的过程都可用于创建此委托类的实例。然后就可以调用委托的Invoke 方法,通过委托实例调用此过程。可以在命名空间、模块、类或结构级别声明委托,但不能在过程内声明。每个委托类都定义一个被传递对象方法规范的构造函数。委托构造函数的参数必须是对方法或lambda 表达式的引用。若要指定对方法的引用,请使用下面的语法:

AddressOf [expression.]methodname

expression 的编译时类型必须是类或接口的名称,而该类或接口包含签名与委托类的签名相匹配的指定名称的方法。methodname 可以是共享方法,也可以是实例方法。即使为类的默认方法创建了委托,methodname 也不是可选项。

若要指定lambda 表达式,请使用下面的语法:

Function ([parm As type, parm2 As type2,...]) expression

函数的签名必须与委托类型的签名相匹配。有关lambda 表达式的更多信息,请参见Lambda 表达式。

                   (更多关于委托的说明,可以看MSDN

   委托的定义和调用也是三步:

     定义:

Delegate Sub 名称(参数1,参数2..)

这里可以带参数,也可以没有参数,要看你下面要委托的过程有没有参数,总之委托的名称要与被委托的过程名参数一至。

实例化: 

Dim Dg_txt As New Dg(AddressOf 过程名)   实例化

      委托:

        Me.Invoke(Dg_txt,参数1…)

下面看一个完整的多线程及委托的实例:

     此实例是实现二个Textbox控件同时飙数字,二个控件飙数字快慢不同,是通过二个线程控制的。

  

      在窗体上绘2TextBox和一个按扭

 

ImportsSystem

ImportsSystem.Threading

Public Class Form1

    DimTd As System.Threading.Thread '定义一个线程

    DimSd As System.Threading.Thread

    DimAsInt32

    Delegate Sub Dg(ByValAsInt32, ByVal obj AsTextBox)

    PrivateSub Button1_Click(ByValsender As System.Object, ByValAs System.EventArgs) Handles Button1.Click

 

        Td = New System.Threading.Thread(AddressOf abc) '实例化,指向abc过程

        Td.Start() '开始运行线程

        Sd = New System.Threading.Thread(AddressOf ab)   '实例化,指向ab过程

        Sd.Start() '开始运行线程

    End Sub

    Subabc()          'Textbox1的线程

        DimDg_txt As New Dg(AddressOf txt)

        ForMe.n = 0 To 100000000

            Me.Invoke(Dg_txt,n, TextBox1)

           System.Threading.Thread.Sleep(10) '让它走慢一点

        Next

    EndSub

    Subab()           'Textbox2的线程

        Dim Dg_txt As New Dg(AddressOftxt)

        DimAs Int32

        For i = 0 To 2000000

            Me.Invoke(Dg_txt,i, TextBox2)      '这里Invoke有三个参数,而过程txt只有二个参数

           System.Threading.Thread.Sleep(100) '比Textbox1慢10倍

        Next

    EndSub

 

    Private Sub Form1_FormClosed(ByValsender AsObject,ByValAsSystem.Windows.Forms.FormClosedEventArgs) HandlesMe.FormClosed

        Td.Abort()   '中止线程

        Sd.Abort()

    EndSub

    '----------------------------------------------------------------

    '---这个过程用到了参数,Textbox1和Textbox2都是通过此过程来赋值

    Sub txt(ByValAs Int32, ByValobj As TextBox)

        Dim As 


相关教程