Class Design and Threading

G

Guest

I have been working on a problem for over two months now, but I can't seem to
get past it.

I have a custom class that makes an remoting call to a web server to
retrieve data. I don't want the UI to "hang" while this process is occuring,
so I have the custom class perform the remoting call on a seperate thread.
When the thread has retrieved all of the data is uses the RaiseEvent keyword.
The event is handled by the UI and is instructed to show a new form (not a
messagebox). The new form flashes up and then disappears almost immediately
(when I actually want it to stick around for a few seconds). However, if I
call the remoting method directly, when the event is raised it is handled as
expected by the UI. I know that it is probably because the event that is
being raised is actually raised on the new thread, but I'm at a loss how to
get past this.

Here is an example of the code:
Public Class RemotingCallObject
Private _Thrd as System.Threading.Thread
Public Event RemoteCallComplete(ByVal sender as Object, ByVal e as
EventArgs)

public sub new()
_Thrd = New System.Threading.Thread(AddressOf GetWebData)
end sub

public sub AsyncCall
_Thrd.Start()
end sub

public sub GetWebData()
' contact the web server and get the new data
RaiseEvent RemoteCallComplete(Me, Nothing)
End Sub
End Class

This is an excerpt from the winform
Public Class MainForm
' Designer Code

Private WithEvents _RC as New RemotingCallObject

Public Sub OnCallComplete(ByVal sender as object, e as EventArgs)
Handles _RC.RemoteCallComplete
Dim PF as new PopupForm
PF.Show()
End Sub

Public Sub Button1_Click(ByVal sender as Object, ByVal e as EventArgs)
Handles Button1.Click
' Calling this method creates my odd behavior, but does not make
the
' UI unresponsive.
_RC.AsyncCall

' Calling this method works as expected, but makes the UI "hang"
_RC.GetWebData
End Sub
End Class

Thanks for any help.
 
A

Armin Zingler

see inline

CQuick said:
I have been working on a problem for over two months now, but I
can't seem to get past it.

I have a custom class that makes an remoting call to a web server to
retrieve data. I don't want the UI to "hang" while this process is
occuring, so I have the custom class perform the remoting call on a
seperate thread. When the thread has retrieved all of the data is
uses the RaiseEvent keyword. The event is handled by the UI and is
instructed to show a new form (not a messagebox). The new form
flashes up and then disappears almost immediately (when I actually
want it to stick around for a few seconds). However, if I call the
remoting method directly, when the event is raised it is handled as
expected by the UI. I know that it is probably because the event
that is being raised is actually raised on the new thread, but I'm
at a loss how to get past this.

Here is an example of the code:
Public Class RemotingCallObject
Private _Thrd as System.Threading.Thread
Public Event RemoteCallComplete(ByVal sender as Object, ByVal e
as EventArgs)

public sub new()
_Thrd = New System.Threading.Thread(AddressOf GetWebData)
end sub

public sub AsyncCall
_Thrd.Start()
end sub

public sub GetWebData()
' contact the web server and get the new data
RaiseEvent RemoteCallComplete(Me, Nothing)
End Sub
End Class

This is an excerpt from the winform
Public Class MainForm
' Designer Code

Private WithEvents _RC as New RemotingCallObject

Public Sub OnCallComplete(ByVal sender as object, e as EventArgs)
Handles _RC.RemoteCallComplete
Dim PF as new PopupForm
PF.Show()


I had only a short look at the code but it seems you don't have a message
loop here:

Application.run(pf)

Be aware of the fact, that the Form is created by the same thread that
raises the event. In general, a Form (and any control) must never be
accessed by a thread that did not create the Form. In other words, only the
creating thread can do. If you want the other thread to create and show the
Form, you must call Invoke/BeginInvoke on any control that has been created
in the other thread. See also a control's InvokeRequired method to find out
if you are currently running in the thread that created the control. As the
method name says, if not, Invoke/BeginInvoke is required.

End Sub

Public Sub Button1_Click(ByVal sender as Object, ByVal e as
EventArgs) Handles Button1.Click
' Calling this method creates my odd behavior, but does
not make the
' UI unresponsive.
_RC.AsyncCall

' Calling this method works as expected, but makes the UI
"hang" _RC.GetWebData
End Sub
End Class

Thanks for any help.


Armin
 
G

Guest

the trick you are missing is getting your worker thread to switch to the ui
thread. read up on invoke, begininvoke, delegates and so forth. there are
articles in the online help about vb worker threads and ui threads.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top