 |
 |

12-13-2004, 06:03 AM
|
|
Freshman
|
|
Join Date: Dec 2004
Posts: 41
|
|
Multithreading With Sockets
|
I have created a sockets client class which connects to a specified IP/Port and sends/receives data to/from it.
Here's a bit of code
client = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
...
client.BeginConnect(remoteEP, AddressOf sockConnected, client)
So sub sockConnected will be called as soon as connection is established. This is asynchronous call, so a new thread is created.
In that sub i have a code to begin receive which is also asynchronous call, but before that an event ir raised. Event is also raised when something is received form the socket. And here's my problem:
Event handlers are called in the thread from which they were raised, so they are not in the main thread. Event handlers cause some problems for me when I try to interract with the UI. And I can't create a new instance of a child form using these event handlers because of that reason as all child windows must be created in the thread that the parent form was created.
My question is:
Is there any way to make event handlers to execute in the parent thread instead of thread they were raised?
Thanks in advance.
|
|

12-13-2004, 01:16 PM
|
 |
Senior Contributor
* Expert *
|
|
Join Date: Nov 2002
Location: Ohio, USA
Posts: 1,828
|
|
|
No.
What you can do though is update your main form through delegates. The delegates can be called from any thread, but will execute in their original thread (and in this case, the UI thread). This will allow you to update, manipulate, etc your UI (provided you make a delegate for whatever you need to do) in a manner that Windows will like.
|
__________________
RandomIRC - Your neighborhood's friendly IRC channel (irc.randomirc.com - #code)
"Perl - The only language that looks the same before and after RSA encryption."
|

12-13-2004, 01:27 PM
|
|
Freshman
|
|
Join Date: Dec 2004
Posts: 41
|
|
Quote:
|
Originally Posted by excaliber
No.
What you can do though is update your main form through delegates. The delegates can be called from any thread, but will execute in their original thread (and in this case, the UI thread). This will allow you to update, manipulate, etc your UI (provided you make a delegate for whatever you need to do) in a manner that Windows will like.
|
So, as I understand, the answer to my question is actually "Yes". If a delegate function can perform any task, this means it can actually raise events, so what I must do is to change my program so that the asynchronous call is not raising any events, but is calling a delegate, which is raising events, so now class events will be handled in forms' thread.
Am I correct?
|
|

12-13-2004, 08:20 PM
|
 |
Senior Contributor
* Expert *
|
|
Join Date: Nov 2002
Location: Ohio, USA
Posts: 1,828
|
|
Well, possibly. Technically, a delegate and an event are the same thing (I've never actually used a custom event, I've always just used delegates). Delegates can only be created by refencing it to a sub routine (essentially the event handler). Because of my lack of knowledge in custom events, I'm not sure if you can declare a delegate that points to an event. And again, Asynch procedures are invoked and passed the address of a sub, I'm not sure if it will accept a delegate sub instead. Try it though, it might work beautifully.
Alternatively, if that doesnt work, you can just add one more layer by keeping the event. Your asynch event handler gets raised, then it invokes the delegate which raises the "pseudo-event handler" on the main thread.
So, one of those ways will work, the first being perhaps more elegant, the second being a little more code/wheels within wheels. Good luck, and let me know how it goes! That might clean up my asynch code a bit.
|
__________________
RandomIRC - Your neighborhood's friendly IRC channel (irc.randomirc.com - #code)
"Perl - The only language that looks the same before and after RSA encryption."
|

12-14-2004, 02:08 AM
|
|
Freshman
|
|
Join Date: Dec 2004
Posts: 41
|
|
Well, ok. I have read very many articles about asynchronous programming and still can't understand, how to solve my problem. I'm not sure how to create a custom event handler that would handle an event that is raised in a different thread than the one where it should be processed in.
I am pastin some code with explanations:
Sockets class:
Code:
Public Sub Connect(ByVal RemoteHostName As String, ByVal RemotePort As Integer)
-------
'Connect and trigger sub 'sockConnected' when connected.
client.BeginConnect(remoteEP, AddressOf sockConnected, client)
End Sub
Private Sub sockConnected(ByVal ar As IAsyncResult)
Dim state As New StateObject
state.workSocket = client
'Begin to receive data from server.
client.BeginReceive(state.buffer, 0, state.BufferSize, 0, AddressOf sockDataArrival, state)
RaiseEvent onConnect()
Event is raised here, and it is handled in the same thread where SockConnected runs. I need it to execute in the main thread instead.
End Sub
Private Sub sockDataArrival(ByVal ar As IAsyncResult)
Dim state As StateObject = CType(ar.AsyncState, StateObject)
Dim client As Socket = state.workSocket
Dim bytesRead As Integer
bytesRead = client.EndReceive(ar)
Dim Data() As Byte = state.buffer
If bytesRead = 0 Then
-----------------
'Close the socket
End If
client.BeginReceive(state.buffer, 0, state.BufferSize, 0, AddressOf sockDataArrival, state)
RaiseEvent onDataArrival(Data, bytesRead)
The same here
End Sub
I'm a bit lost, because I'm new to threading and asynchronous calls.
Maybe somebody could give a little help on delegates? Where to declare it e.t.c.
|
|

12-14-2004, 10:23 AM
|
|
Freshman
|
|
Join Date: Dec 2004
Posts: 41
|
|
|
Ok, so I managed to create a delegate, pass it to a class and to invoke it. But that didn't help. Sub is still called in the thread it was invoked. What am I doing wrong?
|
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
|
|
|
| Thread Tools |
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|
|
|
|
 |
|