VB.NET并行与分布式编程(6)-线程与内核同步[11]

Imports System
Imports System.Threading
Imports System.Runtime.InteropServices
Imports System.Diagnostics
Imports System.Diagnostics.ThreadState


Module Module1


    '定义异步方法
    Delegate Function myAdds(ByVal num As Integer, <Out()> ByRef threadid As Integer) As Long

    <MTAThread()> _
    Sub Main()




        '定义IAsyncResult
        Dim myasyncresult As IAsyncResult

        '定义需要异步执行的方法
        Dim myadd As myAdds = New myAdds(AddressOf mythreadrun)

        '定义计算结果存放处
        Dim resultvalue As Long

        '异步线程调用号
        Dim threadid As Integer



    

        '异步调用
        myasyncresult = myadd.BeginInvoke(5000, threadid, Nothing, Nothing)
        Thread.Sleep(0)
        Console.Write("{0},开始执行线程,主线程{1}号正在等待", Now.ToLongTimeString, Thread.CurrentThread.ManagedThreadId)
        '等待并执行其它代码

     While Not myasyncresult.IsCompleted
            Console.Write(".")
            Thread.Sleep(10)
        End While





        '异步调用完成,返回结果
        resultvalue = myadd.EndInvoke(threadid, myasyncresult)

        '线程执行完毕   
        Console.WriteLine("{0}号线程计算结果为:{1}", threadid, resultvalue)

    End Sub
    Public Function mythreadrun(ByVal num As Integer, <Out()> ByRef threadid As Integer) As Long
        Dim mynum As Integer
        Dim jg As Long = 0
        threadid = Thread.CurrentThread.ManagedThreadId
        Try
            For mynum = 1 To num
                jg += mynum
                Thread.Sleep(1)
            Next
            Console.WriteLine(threadid & "号线程  " & Now.ToLongTimeString & "线程运行完毕!")
        Catch
            Console.WriteLine(threadid & "号线程  " & Now.ToLongTimeString & "线程异常终止!")
            '终止线程
            Thread.CurrentThread.Abort()
        End Try
        Return jg
    End Function
End Module

上面的代码中, 我们使用IAsyncResult的IsCompleted属性完成上节代码类似的功能,轮询工作线程,如果工作线程没有完成,则IsCompleted为False,则主线程继续自己的工作,输出一个点,同时再休眠10秒

     While Not myasyncresult.IsCompleted
            Console.Write(".")
            Thread.Sleep(10)
        End While

 



 

 

前面几个异步调用的例子,我们都在主线程对计算结果进行输出,我们下面把输出计算结果的工作移到回调方法中,启动异步调用,我们可以传递一个回调函数做为参数给BeginInvoke,由回调函数对工作线程,即被调用的线程的结果进行处理,主线程不再处理。

有几个小知识点

a)IAsyncResult.AsyncState 属性

 

获取用户定义的对象,它限定或包含关于异步操作的信息。

 

此属性返回一个对象,该对象是启动异步操作的方法的最后一个参数。

 

使用AsyncState  属性来向回调方法传递信息。

被调用者实现此属性以允许异步操作的调用方获取在操作开始指定的应用程序定义的对象。 
调用者可以使用此对象将异步操作的状态信息传递给回调函数。 

    Public Sub myfinished(ByVal ar As IAsyncResult)
        '回调函数完成将计算结果显示的功能,不再在主线程中显示计算结果
        Dim threadid As Integer
        Dim caller As myAdds = CType(ar.AsyncState, myAdds)
        Dim returnvalue As Long = caller.EndInvoke(threadid, ar)

        Console.WriteLine("工作线程{0}号执行完毕,计算结果为{1}", threadid, returnvalue)
    End Sub

 

b)异步调用的最后一个参数就是传递给回调函数的,我们在这里把需要异步执行的方法myadd传入,方法对象会存入

IAsyncResult.AsyncState 属性中

        myasyncresult = myadd.BeginInvoke(5000, threadid, AddressOf myfinished, myadd)
完整代码如下:

 

Imports System
Imports System.Threading
Imports System.Runtime.InteropServices
Imports System.Diagnostics
Imports System.Diagnostics.ThreadState


Module Module1


    '定义异步方法
    Delegate Function myAdds(ByVal num As Integer, <Out()> ByRef threadid As Integer) As Long

    <MTAThread()> _
    Sub Main()




        '定义IAsyncResult
        Dim myasyncresult As IAsyncResult

        '定义需要异步执行的方法
        Dim myadd As myAdds = New myAdds(AddressOf mythreadrun)

        '定义计算结果存放处
        Dim resultvalue As Long

        '异步线程调用号
        Dim threadid As Integer





        '异步调用
        myasyncresult = myadd.BeginInvoke(5000, threadid, AddressOf myfinished, myadd)
        Console.WriteLine("{0},开始执行线程,主线程{1}号正在等待", Now.ToLongTimeString, Thread.CurrentThread.ManagedThreadId)
        Thread.Sleep(0)
        Console.WriteLine("工作线程正在运行,按任意健结束主线程.....")
        Console.ReadLine()


    End Sub
    Public Function mythreadrun(ByVal num As Integer, <Out()> ByRef threadid As Integer) As Long
        Dim mynum As Integer
        Dim jg As Long = 0
        threadid = Thread.CurrentThread.ManagedThreadId
        Try
            For mynum = 1 To num
                jg += mynum
                Thread.Sleep(1)
            Next
            Console.WriteLine(threadid & "号线程  " & Now.ToLongTimeString & "线程运行完毕!")
        Catch
            Console.WriteLine(threadid & "号线程  " & Now.ToLongTimeString & "线程异常终止!")
            '终止线程
            Thread.CurrentThread.Abort()
        End Try
        Return jg
    End Function
    Public Sub myfinished(ByVal ar As IAsyncResult)
        '回调函数完成将计算结果显示的功能,不再在主线程中显示计算结果
        Dim threadid As Integer
        Dim caller As myAdds = CType(ar.AsyncState, myAdds)
        Dim returnvalue As Long = caller.EndInvoke(threadid, ar)

        Console.WriteLine("工作线程{0}号执行完毕,计算结果为{1}", threadid, returnvalue)
    End Sub

End Module

 



 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值