【异步编程】异步执行,获取返回值
上次在看线程时,知道了委托.好不容易搞明白了委托怎么写,
原先的问题http://topic.csdn.net/u/20111019/17/ac098c48-ed25-4e1f-acd0-ec192ca44eac.html
又想知道线程什么时候结束,或者我想知道我授予线程的过程执行的怎么样了.
如是到网上查,omg,异步..回调执行,
我找了一个一例子,然后照葫芦画瓢,但是得不到正确的结果.
//我的以下是想实现将form的text修改一下,然后线程执行完毕后,提示我一下.
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
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 不是一个概念
[解决办法]
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
[解决办法]