|
-
Nov 22nd, 2004, 05:01 AM
#1
Thread Starter
Hyperactive Member
Multithread help
Hi all,
I'm writing an app that will spawn two threads sending request to remote system for long waiting results, and these results will be displayed in datagrids inside a tabcontrol.
I just follow the code in M$ that use BeginInvoke with callback as below:
Worker class:
Public clsWorker
Public Sub Exec(ByVal Func as string, ByVal ID as string, ByRef dt as datatable)
Debug.WriteLine(strFunc & " running at thread " & AppDomain.GetCurrentThreadId)
Dim thread As Thread = thread.CurrentThread
thread.Name = strFunc
'...call the remote function using Func & ID, and fill dt as return....
End Sub
End Class
Main class:
Public Class frmSomething
Inherits ....
Dim dt1, dt2 as datatable
Public Delegate Sub ExecDelegate(...)
Public Delegate Sub UpdateUIDelegate(ByVal strFunc As String)
Dim dlgUI As UpdateUIDelegate = New UpdateUIDelegate(AddressOf UpdateUI_1)
Public Sub UpdateUI_1(ByVal strFunc As String)
Debug.WriteLine("UpdateUI_1 running at thread " & AppDomain.GetCurrentThreadId)
If strFunc = "somevalue" Then
grdA.DataSource = dt
Else
grdB.DataSource = dt1
End If
End Sub
Public Sub UpdateUI(ByVal ar as IAsyncResult)
Debug.WriteLine("UpdateUI running at thread " & AppDomain.GetCurrentThreadId)
Dim dlgt As ExecDelegate = CType(ar.AsyncState, ExecDelegate)
' Call EndInvoke to retrieve the results.
If Thread.CurrentThread.Name = "somevalue" Then
dlgt.EndInvoke(dt, lngErr, strErr, ar)
Else
dlgt.EndInvoke(dt1, lngErr, strErr, ar)
End If
dlgUI.Invoke(Thread.CurrentThread.Name)
End Sub
Private Sub frmSomething_Load(....)
Debug.WriteLine("Main running at thread " & AppDomain.GetCurrentThreadId)
Dim w As New clsMQWorker
Dim dlgExec As ExecDelegate = New ExecDelegate(AddressOf w.Exec)
dlgExec.BeginInvoke("AAA", "C2345", dt, AddressOf UpdateUI, dlgExec)
dlgExec.BeginInvoke("BBB", "C0012", dt1, AddressOf UpdateUI, dlgExec)
End Sub
As I read several times from documents that the update of UI shouldn't be run in the spawned threads, so when the remote function callback (calling UpdateUI), I try to check Me.InvokeRequired, and see if I need to call the UpdateUI_1 delegate. However, I found that Me.InvokeRequired always return true (as in debug.writeline)!
On the other hand, when update UI happens in the worker thread, I see no noticable problems.
Question:
1. How can I switch to the main thread to update UI?
2. Since the dt parameter is ByRef, when worker thread update the dt with some records and returns, dt1 / dt2 in the main thread should have a value. However, when I call EndInvoke and pass another variable (say dt3), I found that dt1 and dt2 remain Nothing! Actually at which calls will the byref variable in "callee" pass back to "caller"??
3. For passing variable ByRef and ByVal, if the data size is large, which method is faster? I think ByRef should be faster but it invokes synchronization problem, is the true?
Thx a lot!
-
Nov 22nd, 2004, 09:43 PM
#2
Thread Starter
Hyperactive Member
HI all,
I know why I can't switch thread, because in the UpdateUI function, I should call Me.BeginInvoke with the UpdateUI delegate instead of calling UpdateUI delegate's BeginInvoke.
Thx!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|