首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > VB Dotnet >

【异步编程】异步执行,获取返回值,该如何处理

2012-01-21 
【异步编程】异步执行,获取返回值上次在看线程时,知道了委托.好不容易搞明白了委托怎么写,原先的问题http://

【异步编程】异步执行,获取返回值
上次在看线程时,知道了委托.好不容易搞明白了委托怎么写,
原先的问题http://topic.csdn.net/u/20111019/17/ac098c48-ed25-4e1f-acd0-ec192ca44eac.html
又想知道线程什么时候结束,或者我想知道我授予线程的过程执行的怎么样了.
如是到网上查,omg,异步..回调执行,
我找了一个一例子,然后照葫芦画瓢,但是得不到正确的结果.

//我的以下是想实现将form的text修改一下,然后线程执行完毕后,提示我一下.

VB.NET code
Imports System.ThreadingImports System.Runtime.Remoting.MessagingPublic Class Form1    Private Delegate Sub myDelegate(ByVal myString As String) '自定义一个委托    Dim MyThread As System.Threading.Thread    Private Sub SetWindowText(ByVal myString As String) '与委托相同签名的函数或过程        Me.Text = myString    End Sub    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click        MyThread = New System.Threading.Thread(AddressOf sum)        MyThread.Start()    End Sub    Private Sub sum()        Dim sum As Single        sum = Rnd()        Dim b As myDelegate = New myDelegate(AddressOf SetWindowText)        'Me.Invoke(New myDelegate(AddressOf SetWindowText), sum.ToString) '委托的调用        'Me.Invoke(b, sum.ToString)        '这儿将me.invoke替换为下面的BeginInvoke又会导致非法调用控件啊.        Dim myar As IAsyncResult = b.BeginInvoke(sum.ToString, New AsyncCallback(AddressOf CallBackThread), "执行完毕!")    End Sub    Private Sub CallBackThread(ByVal myar As IAsyncResult)        msgbox( "当前线程是:" & System.Threading.Thread.CurrentThread.ManagedThreadId)        Dim ar As AsyncResult = CType(myar, AsyncResult)        Dim b As myDelegate = CType(ar.AsyncDelegate, myDelegate)        b.EndInvoke(myar)        MsgBox(myar.AsyncState.ToString)    End SubEnd Class


请教在这一方面有兴趣和大神.

[解决办法]
委托的意思是 在A线程中调用B线程的消息循环执行某段代码。

线程可以理解成一个独立的过程(SUB)。

当调用委托时,委托部分的代码将在另一线程中执行。

线程状态可以直接调用Thread的属性来查询。

线程中的代码执行的位置,只能用一些公共状态值来判断。


[解决办法]
探讨
上次在看线程时,知道了委托.好不容易搞明白了委托怎么写,
原先的问题http://topic.csdn.net/u/20111019/17/ac098c48-ed25-4e1f-acd0-ec192ca44eac.html
又想知道线程什么时候结束,或者我想知道我授予线程的过程执行的怎么样了.
如是到网上查,omg,异步..回调执行,
我找了一个一例子,然后照葫芦画瓢,但是得不到正确的结果……

[解决办法]
再补充一下

线程可以理解成一个独立的过程(SUB)。

过程结束(END SUB)时,也意味着线程结束。

在过程结束之前,调用的委托,有可能委托代码执行时,线程已经结束。

Invoke跟BeginInvoke是两个概念,Invoke由控件继承表示A线程让B线程上执行某段代码

BeginInvoke则表示在当前线程A上开启一个新线程B进行异步操作。

LZ的代码在A线程上启动了BeginInvoke,于是开启了线程B,当线程B返回EndInvoke时,直接调用了线程C上的控件,于是就报错了。


[解决办法]
VB.NET code
Private Delegate Sub BeginInvokeDelegate()    Private Sub SetTextBoxText()        lbl2.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")    End Sub    Private Sub ThreadMethod()        Thread.Sleep(3000)        Me.BeginInvoke(New BeginInvokeDelegate(AddressOf SetTextBoxText))    End Sub    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load        Dim t As New Thread(AddressOf ThreadMethod)        t.Start()        lbl1.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")    End Sub
[解决办法]
Private Delegate Sub myDelegate(ByVal myString As String)
Dim MyThread As System.Threading.Thread

Private Sub SetWindowText(ByVal myString As String)
Debug.Print("SetWindowText线程是:" & System.Threading.Thread.CurrentThread.ManagedThreadId)
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click


MyThread = New System.Threading.Thread(AddressOf sum)
MyThread.Start()
Debug.Print("Button线程是:" & System.Threading.Thread.CurrentThread.ManagedThreadId)
End Sub

Private Sub sum()
Dim sum As Single
sum = Rnd()
Dim b As myDelegate = New myDelegate(AddressOf SetWindowText)
Dim myar As IAsyncResult = b.BeginInvoke(sum.ToString, New AsyncCallback(AddressOf CallBackThread), "执行完毕!")
Debug.Print("sum线程是:" & System.Threading.Thread.CurrentThread.ManagedThreadId)
End Sub

Private Sub CallBackThread(ByVal myar As IAsyncResult)
Debug.Print("CallBackThread线程是:" & System.Threading.Thread.CurrentThread.ManagedThreadId)
End Sub

会看到这段代码产生了三个线程。
[解决办法]
首先 你要明白 Control.BeginInvoke 与 Delegate.BeginInvoke 不是一个概念
[解决办法]

VB.NET code
Private Delegate Sub Action()    Private Delegate Sub BeginInvokeDelegate(myString As String, action As Action)    Private Sub SetTextBoxText(myString As String, action As Action)        lbl2.Text = String.Format("我是传参:{0},当前时间:{1}", myString, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))        action()    End Sub    Private Sub ThreadMethod(myString As String)        Thread.Sleep(3000)        Me.BeginInvoke(New BeginInvokeDelegate(AddressOf SetTextBoxText), myString, New Action(AddressOf CallBackSub))    End Sub    Private Sub CallBackSub()        MessageBox.Show("我是CallBack")    End Sub    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load        Dim t As New Thread(AddressOf ThreadMethod)        t.Start("传参")        lbl1.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")    End Sub
[解决办法]
LZ这个有涉及到跨线程调用控件!
 Control.CheckForIllegalCrossThreadCalls = False
LZ在线程调用前加上这句试试看!
记得线程走完要弄回来,毕竟支持跨线程调用控件这样不好
[解决办法]
Control.BeginInvoke 
可以理解为,新开启一个线程A,然后A调用Control.Invoke 等于是省掉一个Thread声明

Delegate.BeginInvoke可以理解为新开启一个线程A 在A上面运行委托的过程,也相当于省掉一个Thread
声明
 
Private Delegate Sub myDelegate(ByRef myString As String)
Dim MyThread As System.Threading.Thread

Private Sub SetWindowText(ByRef Start As String)
Dim i As Long
Dim n As Long
n = CLng(Start)
For i = n To n + 200
i += 1
Threading.Thread.Sleep(10)
Next
Start = i
Debug.Print("SetWindowText计算结果:" & i)
Debug.Print("SetWindowText线程是:" & System.Threading.Thread.CurrentThread.ManagedThreadId)
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
MyThread = New System.Threading.Thread(AddressOf sum)
MyThread.Start()
Debug.Print("Button线程是:" & System.Threading.Thread.CurrentThread.ManagedThreadId)
End Sub

Private Sub sum()
Dim n As Integer
Dim b As myDelegate = New myDelegate(AddressOf SetWindowText)
Dim myar As IAsyncResult = b.BeginInvoke(n, New AsyncCallback(AddressOf CallBackThread), "执行结束!")
Threading.Thread.Sleep(10)
If myar.IsCompleted Then '判断是否完成
Debug.Print("委托线程结束")
Else
Debug.Print("委托线程还在继续")
End If
myar.AsyncWaitHandle.WaitOne(100) '另外的线程等待一百毫秒
Debug.Print("sum线程是:" & System.Threading.Thread.CurrentThread.ManagedThreadId)


'Dim s As String = ""
'b.EndInvoke(s, myar)'等待直到返回
'Debug.Print("得到函数的计算返回值" & s)
End Sub

Private Sub CallBackThread(ByVal myar As IAsyncResult)

Dim ar As System.Runtime.Remoting.Messaging.AsyncResult = myar
Dim b As myDelegate = CType(ar.AsyncDelegate, myDelegate)
Dim s As String = ""
b.EndInvoke(s, myar)
Debug.Print("CallBackThread得到函数的计算返回值" & s)
Debug.Print("CallBackThread返回:" & myar.AsyncState)
Debug.Print("CallBackThread线程是:" & System.Threading.Thread.CurrentThread.ManagedThreadId)
End Sub
[解决办法]

探讨
引用:

VB.NET code

Private Delegate Sub Action()
Private Delegate Sub BeginInvokeDelegate(myString As String, action As Action)

Private Sub SetTextBoxText(myString As String, ……

热点排行