Jump to content
xisto Community
Sign in to follow this  
turbopowerdmaxsteel

Help: Multi-threading Trouble In Custom Socket Component

Recommended Posts

I am creating a wrapper component for the System.Net.Sockets.Socket class which would resemble the Winsock control. The basic idea is to do operations such as Connect & Receive asynchronously. The component has events such as Connected, PacketArrival in response to these. To do this, I use the following code:-

 

Socket Code

Imports System.Net.SocketsPublic Class MySocket	Dim Sck As Socket	   ' Socket Object	' Connect Method	Sub Connect(ByVal Host As String, ByVal Port As Integer)		Sck = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)		' Connect Multithreaded		Sck.BeginConnect(Host, Port, New AsyncCallback(AddressOf ConnectCallBack), Sck)	End Sub	' CallBack For System.Net.Sockets.Socket's asynchronous Connect Operation	Private Sub ConnectCallBack(ByVal ar As IAsyncResult)		Sck.EndConnect(ar)		RaiseEvent Connected()	End Sub	' The event to Notify the Owner Form	Public Event Connected()End Class

The problem here is that the Connected event is raised on the thread of the asynchronous Connect method of the Socket. So, if I try to access any control from this event's handler, a Cross-thread operation not valid exception is generated.

 

Window Code

Public Class Form1	Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load		mSck.Connect("microsoft.com;, 80)	End Sub	Private Sub mSck_Connected() Handles mSck.Connected		' Set the Window Text to Notify this Event		Me.Text = "Connected"	End SubEnd Class

I am able to get past this by following the process stated in MSDN for making thread safe calls.

Public Class Form1	Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load		mSck.Connect("microsoft.com;, 80)	End Sub	Delegate Sub ConnectedCallBack()	Private Sub mSck_Connected() Handles mSck.Connected		Dim D As New ConnectedCallBack(AddressOf SocketConnected)		Me.Invoke(D)	End Sub	Sub SocketConnected()		' Set the Window Text to Notify this Event		Me.Text = "Connected"	End SubEnd Class

While, this works, I am not satisfied with having to create callbacks for these routine events. Is there a way to raise the event in the same thread as that of the Form?

Share this post


Link to post
Share on other sites

While, this works, I am not satisfied with having to create callbacks for these routine events. Is there a way to raise the event in the same thread as that of the Form?

I don't think you have much choices. I'm also trying to learn more about multithreading, I found that it's actually very tedious to do. I've written a multithreaded multimedia software, running from 5 to 20 threads at a time. Took me quite a while to find tricks that can synchronize them all. Also, sometime when it fail, it doesn't just stop, but it runs for a while, then start to show some funny behavior. So have to spend more time debugging.
Anyway, as for your case, i've done something similar as well, but i'm using a main tread to loop and wait for the event, and then dispatches the job to worker threads. The worker thread contained in a separated class. Called using a function, and that function will then create the thread to do the job. So, when i call the function, a new instance is instantiated, which everything contain within itself. To keep track of the worker thread, you can add that into an array. Then have the main thread check for a bit that indicate if the job is done, then you can dispose and remove it from the array. The checking can be done at a preset duration, depending on the job load, or whenever a new worker thread need to be added.

Share this post


Link to post
Share on other sites

I have manged to get the job done. What I did was inherit the class fron System.Windows.Forms.Control. This allows Invoke to be called from within the class and thus removes the overhead of having to do so everytime. This comes at a cost, though. The Socket control is no longer the design time only visible thingy. So, I had to handle the Paint messages for the control and it is now quite similar to the Winsock control.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...

Important Information

Terms of Use | Privacy Policy | Guidelines | We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.