Go Back  Xtreme Visual Basic Talk > Visual Basic .NET (2002/2003/2005/2008, including Express editions) > .NET Communications > Multithreading With Sockets


Reply
 
Thread Tools Display Modes
  #1  
Old 12-13-2004, 06:03 AM
Slow-Mo Slow-Mo is offline
Freshman
 
Join Date: Dec 2004
Posts: 41
Default 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.
Reply With Quote
  #2  
Old 12-13-2004, 01:16 PM
excaliber's Avatar
excaliber excaliber is offline
Senior Contributor

* Expert *
 
Join Date: Nov 2002
Location: Ohio, USA
Posts: 1,828
Default

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."
Reply With Quote
  #3  
Old 12-13-2004, 01:27 PM
Slow-Mo Slow-Mo is offline
Freshman
 
Join Date: Dec 2004
Posts: 41
Default

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?
Reply With Quote
  #4  
Old 12-13-2004, 08:20 PM
excaliber's Avatar
excaliber excaliber is offline
Senior Contributor

* Expert *
 
Join Date: Nov 2002
Location: Ohio, USA
Posts: 1,828
Default

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."
Reply With Quote
  #5  
Old 12-14-2004, 02:08 AM
Slow-Mo Slow-Mo is offline
Freshman
 
Join Date: Dec 2004
Posts: 41
Default

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.
Reply With Quote
  #6  
Old 12-14-2004, 10:23 AM
Slow-Mo Slow-Mo is offline
Freshman
 
Join Date: Dec 2004
Posts: 41
Default

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?
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
 
 
-->